<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>Peter Bex</name>
  </author>
  <generator uri="https://github.com/ursetto/atom-egg" version="0.1.5">atom egg for Chicken</generator>
  <id>tag:more-magic,2012-08-22:/</id>
  <link href="https://www.more-magic.net/" rel="alternate" type="text/html" />
  <link href="https://www.more-magic.net/feed.atom" rel="self" type="application/atom+xml" />
  <subtitle type="text">Cautionary tales from a programmer</subtitle>
  <title type="text">More Magic</title>
  <updated>2026-01-21T11:48:15Z</updated>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;The European Commission has posted a &lt;a href="https://lwn.net/Articles/1053107/" class="external"&gt;&amp;quot;call for evidence&amp;quot;&lt;/a&gt; on open source for digital sovereignty.  This seeks feedback from the public on how to reduce its dependency on software from non-EU companies through Free and Open Source Software (FOSS).&lt;/p&gt;
&lt;p&gt;This is my response, with proper formatting (the web form replies all seem to have gotten their spaces collapsed) and for future reference.&lt;/p&gt;&lt;a href="#the-added-value-of-foss"&gt;
&lt;h2 id="the-added-value-of-foss"&gt;The added value of FOSS&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;In times where international relations are tense, it is wise to invest in digital sovereignty.  For example, recently there was a controversy surrounding the International Criminal Court losing access to e-mail hosted by Microsoft, a US company, for political reasons.&lt;/p&gt;
&lt;p&gt;A year earlier, a faulty CrowdStrike update caused the largest IT outage in history.  This was an accident, but it was a good reminder of the power that rests in foreign hands.  We have to consider the possibility of a foreign government pressuring a company to issue a malicious update on purpose.  This update could target only specific countries.&lt;/p&gt;
&lt;p&gt;Bringing essential infrastructure into EU hands makes sense.  But why does this have to be FOSS?  For instance, the CrowdStrike incident could also have happened with FOSS.&lt;/p&gt;
&lt;p&gt;With FOSS, one does not have to trust a single company to maintain high code quality and security.  Independent security researchers and programmers will be looking at this code with a fresh perspective.  It is also an industry truism that FOSS code tends to be of higher quality, simply because releasing bad code is too embarrassing.&lt;/p&gt;
&lt;p&gt;FOSS also reduces vendor lock-in.  One can switch vendors and keep using the same product when for example the vendor:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;goes bankrupt,&lt;/li&gt;
&lt;li&gt;drops support for the product,&lt;/li&gt;
&lt;li&gt;drastically increases prices,&lt;/li&gt;
&lt;li&gt;decides on a different direction for the product than the user wants,&lt;/li&gt;
&lt;li&gt;or gets acquired by a foreign company.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Therefore, FOSS brings sovereignty by not being at the mercy of a single vendor.&lt;/p&gt;&lt;a href="#public-sector-and-consultancies"&gt;
&lt;h2 id="public-sector-and-consultancies"&gt;Public sector and consultancies&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;The EU can set a good example by starting in the public sector: government EU organisations and those of the member states, as well as semi-government organisations like universities and libraries.  Closed source software still reigns supreme there.  Only &amp;quot;established&amp;quot; companies may apply to tenders.  These often employ professionals certified in proprietary tech.  This encourages vendor lock-in.  The existing dependency ensures lock-in for future projects, as compatibility is often a key requirement.&lt;/p&gt;
&lt;p&gt;These same vendors are ruthless and have repeatedly sabotaged FOSS migrations.  Microsoft was involved in multiple bribery scandals in The Netherlands, Romania, Italy and Hungary, for example.  There have also been allegations of illegal deals that were never investigated, such as with the LiMux project in Munich.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;How the EU can help:&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;Fully&lt;/i&gt; commit to FOSS.  Set a date by which all software used by the public sector must be FOSS and running on hardware within the EU, at fully EU-owned companies.  No compromises, no excuses and no easy outs - those were the bane of previous efforts.&lt;/li&gt;
&lt;li&gt;Map out missing requirements and pay EU consultancy firms to improve FOSS where it is lacking.  This will also make said software also more attractive for large private organisations that provide essential services in the EU.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;Concrete examples&lt;/b&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Many EU and member state institutes rely on American services for hosting or securing their e-mail.  E-mail software is a complete commodity, for which there are good European alternatives, based on FOSS.  It should be easy to switch.&lt;/li&gt;
&lt;li&gt;Workstations for public servants typically run on Windows and use Microsoft Office.  Switch these to a proven open operating system like Linux and office suite like LibreOffice.&lt;/li&gt;&lt;/ul&gt;&lt;a href="#education-and-mind-share"&gt;
&lt;h2 id="education-and-mind-share"&gt;Education and mind share&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;In schools, informatics is typically taught using proprietary software.  This is often cloud software.  Schools do not have the expertise or funds to run their own servers.  Therefore, they use the easy option that teachers are familiar with: &amp;quot;free&amp;quot; online offerings from US Big Tech.  Network effects ensure deeper entrenchment.  Big Tech offers steep discounts for educational licenses for these exact reasons.&lt;/p&gt;
&lt;p&gt;Vocational schools focus on proprietary tech most used in industry. This goes beyond IT studies.  For example, statistics and psychology courses use SPSS over PSPP or R.  Mathematics and physics courses use MATLAB over GNU Octave.  Engineering courses use AutoCAD instead of FreeCAD or LibreCAD.&lt;/p&gt;
&lt;p&gt;A focus on the impact of tech choices in education could change the situation from the ground up.  In high school, there could be a place (e.g. in civic education class) to focus on the impact of tech choices on society.  This goes beyond domestic versus foreign &amp;quot;cloud&amp;quot; hosting and open versus proprietary code.  For example, studies show that social media can have harmful effects on mental well-being, societal cohesion and even democracy.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;How the EU can help&lt;/b&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Provide funding for course material, and/or create a certification programme for suitable course material to wean schools off of Big Tech software.&lt;/li&gt;
&lt;li&gt;Start an education campaign aimed at the broader public in order to explain why closed software and the non-EU cloud are harmful.  For example, it could focus on concrete issues that affect anyone like data protection, privacy and resistance against &amp;quot;enshittification&amp;quot; such as unwanted ads, price hikes and feature removal.&lt;/li&gt;
&lt;li&gt;For the existing work force, the EU can fund training in open alternatives so that people feel confident with these alternatives. Such training should include a theoretical component to discuss the benefits of using open alternatives to ensure people are fully on board.&lt;/li&gt;&lt;/ul&gt;&lt;a href="#existing-foss-companies-and-economic-situation"&gt;
&lt;h2 id="existing-foss-companies-and-economic-situation"&gt;Existing FOSS companies and economic situation&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;The EU has plenty of FOSS businesses already.  A handful of examples: SUSE was one of the first companies to provide FOSS server and desktop operating systems for the enterprise.  Tuta and Proton Mail provide innovative secure e-mail solutions.  Nextcloud offers cloud-based content collaboration tools.  GitLab and Codeberg offer code hosting platforms.&lt;/p&gt;
&lt;p&gt;These companies are innovative and profitable, but small in the global market place.  Competitors from the US benefit from economies of scale.  The initial US market is a large country with a single language and minimal legislation.  This allows for quick domestic growth followed by global expansion.  The EU market is more fragmented so it is harder to gain a foothold, requiring more up front investment to e.g. support the languages spoken in the EU.&lt;/p&gt;
&lt;p&gt;Venture capital is also less likely to invest in the EU because of stricter legislation.  Because FOSS solutions give competing companies a chance to offer the product, the returns on investment are lower than with proprietary software where a single company has a monopoly on the software.&lt;/p&gt;
&lt;p&gt;Some EU companies have realised that this legislation is an asset: it allows for differentiation from US-based offerings.  EU software can compete in the global market place on its own merits.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;How the EU can help:&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Promote tech sovereignty to countries across the world.  Start with countries who are not formally allied to the US.  This could help EU companies to expand into the global market.&lt;/li&gt;
&lt;li&gt;Help EU companies become more well-known by organising trade shows exhibiting only FOSS EU companies.&lt;/li&gt;
&lt;li&gt;Provide funding to organisations like the FSF Europe to run awareness campaigns about FOSS alternatives.&lt;/li&gt;
&lt;li&gt;Perhaps controversial: heavily tax proprietary, non-EU software or provide tax breaks for FOSS EU software to level the playing field.&lt;/li&gt;
&lt;li&gt;Even more controversially: prevent foreign-owned companies from operating data centers in the EU.  Make it as hard as possible for them to offer high-speed cloud software here.  These data centers are already unpopular, as they use precious water and land, and they only make foreign companies more powerful.&lt;/li&gt;&lt;/ul&gt;&lt;a href="#conclusion"&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;The reasons for dependency on foreign proprietary solutions are systemic.  The causes are various: from inertia and ignorance to market effects and bribery.  The solutions must be equally systemic: from education to policy and funding, all points must be attacked in order to succeed.  This is the only way we can get rid of our dependency on non-EU software.&lt;/p&gt;</content>
    <id>tag:more-magic,2026-01-21:/posts/open-source-in-the-eu.html</id>
    <published>2026-01-21T11:48:15Z</published>
    <title type="text">FOSS for digital sovereignty in the EU</title>
    <updated>2026-01-21T11:48:15Z</updated>
    <link href="https://www.more-magic.net/posts/open-source-in-the-eu.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;I feel a change is happening in how people produce and (want to) consume software, and I want to give my two cents on the matter.&lt;/p&gt;
&lt;p&gt;It has become more mainstream to see people critical of &amp;quot;Big Tech&amp;quot;. &lt;a href="https://en.wikipedia.org/wiki/Enshittification" class="external"&gt;Enshittification&lt;/a&gt; has become a familiar term even outside the geek community.  Obnoxious &amp;quot;AI&amp;quot; features that nobody asked for get crammed into products. Software that spies on its users is awfully common.  Software updates have started crippling existing features, or have deliberately stopped being available, so more new devices can be sold.  Finally, it is increasingly common to get obnoxious ads shoved in your face, &lt;i&gt;even in software you have already paid for&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;In short, it has become hard to really &lt;i&gt;trust&lt;/i&gt; software.  It often does not act in the user's best interest.  At the same time, we are &lt;i&gt;entrusting&lt;/i&gt; software with more and more of our lives.&lt;/p&gt;
&lt;p&gt;Thankfully, new projects are springing up which are using a different governance model.  Instead of a for-profit commercial business, there is a non-profit backing them.  Some examples of more or less popular projects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.signal.org" class="external"&gt;Signal&lt;/a&gt; and &lt;a href="https://www.matrix.org" class="external"&gt;Matrix&lt;/a&gt; for instant messaging,&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bsky.social" class="external"&gt;Bluesky&lt;/a&gt; and &lt;a href="https://www.joinmastodon.org" class="external"&gt;Mastodon&lt;/a&gt; for social media,&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.mozilla.org" class="external"&gt;Mozilla&lt;/a&gt; for web browser, e-mail client and more,&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.proton.me" class="external"&gt;Proton&lt;/a&gt; for e-mail hosting, VPN and more,&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.codeberg.org" class="external"&gt;Codeberg&lt;/a&gt; for code repository hosting,&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.wikipedia.org" class="external"&gt;Wikipedia&lt;/a&gt; and &lt;a href="https://www.archive.org" class="external"&gt;Internet Archive&lt;/a&gt; for all the world's knowledge.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Some of these are older projects, but there seems to be something in the air that is causing more projects to move to non-profit governance, and for people to choose these.&lt;/p&gt;
&lt;p&gt;As I was preparing this article, I saw an announcement that &lt;a href="https://mitchellh.com/writing/ghostty-non-profit" class="external"&gt;ghostty&lt;/a&gt; now has a non-profit organisation behind it.  At the same time, I see more reports from developers &lt;a href="https://eldred.fr/blog/forge-migration/" class="external"&gt;leaving GitHub for Codeberg&lt;/a&gt;, and in the mainstream more and more people are switching to Signal.&lt;/p&gt;&lt;a href="#why-free-and-open-source-software-is-not-enough"&gt;
&lt;h2 id="why-free-and-open-source-software-is-not-enough"&gt;Why free and open source software is not enough&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;From a user perspective, free software and open source software (FOSS) has advantages over proprietary software.  For instance, you can study the code to see what it does.  This alone can deter manufacturers from putting in user-hostile features.  You can also remove or change what you dislike or add features you would like to see.  If you are unable to code, you can usually find someone else to do it for you.&lt;/p&gt;
&lt;p&gt;Unfortunately, this is not enough.  Simply having the ability to see and change the code does not help when the program is a web service. Network effects will ensure that the &amp;quot;main instance&amp;quot; is the only viable place to use this; you have all your data there, and all your friends are there.  And hosting the software yourself is hard for non-technical people.  Even highly technical people often find it too much of a hassle.&lt;/p&gt;
&lt;p&gt;Also, code can be very complex!  Often, only the team behind it can realistically further develop it.  This means you can run it yourself, but still are dependent on the manufacturer for the direction of the product.  This is how you get, for example, AI features in GitLab and ads in Ubuntu Linux.  One can technically remove or disable those features, but it is hard to keep such a modified version (a &lt;i&gt;fork&lt;/i&gt;) up with the manufacturer's more desirable changes.&lt;/p&gt;
&lt;p&gt;The reason is that the companies creating these products are still motivated by profit and increasing shareholder value.  As long as the product still provides (enough) value, users will put up with misfeatures.  The (perceived) cost of switching is too high.&lt;/p&gt;&lt;a href="#non-profit-is-not-a-panacea"&gt;
&lt;h2 id="non-profit-is-not-a-panacea"&gt;Non-profit is not a panacea&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Let us say a non-profit is behind the software.  It is available under a 100% FOSS license.  Then there are still ways things can go downhill. I think this happens most commonly if the funding is not in order.&lt;/p&gt;
&lt;p&gt;For example, Mozilla is often criticised for receiving funding from Google.  In return, it uses Google as the default search.  To make it less dependent on Google, Mozilla acquired &lt;a href="https://en.wikipedia.org/wiki/Pocket_(service)" class="external"&gt;Pocket&lt;/a&gt; and integrated it into the browser.  It also added ads on the home screen. Both of these actions have &lt;i&gt;also&lt;/i&gt; been criticised.  I do not want to pick on Mozilla (I use Firefox every day).  It has clearly been struggling to make ends meet in a way that is consistent with its goals and values.&lt;/p&gt;
&lt;p&gt;I think the biggest risk factor is (ironically) if the non-profit does not have a sustainable business model and has to rely on funding from other groups.  This can compromise the vision, like in Mozilla's case. For web software, the obvious business model is a SaaS platform that offers the software.  This allows the non-profit to make money from the convenience of not having to administer it yourself.&lt;/p&gt;
&lt;p&gt;There is another, probably even better, way to ensure the non-profit will make good decisions.  If the organisation is &lt;i&gt;democratically led&lt;/i&gt; and &lt;i&gt;open for anyone to become a member&lt;/i&gt; like &lt;a href="https://join.codeberg.org/" class="external"&gt;Codeberg e.V. is&lt;/a&gt;, it can be steered by the very users it serves.  This means there is no top-down leadership that may make questionable decisions.  Many thanks to Technomancy for &lt;a href="https://lobste.rs/c/uocnls" class="external"&gt;pointing this out&lt;/a&gt;.&lt;/p&gt;&lt;a href="#what-about-volunteer-driven-efforts"&gt;
&lt;h2 id="what-about-volunteer-driven-efforts"&gt;What about volunteer driven efforts?&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Ah, good old volunteer driven FOSS.  Personally, I prefer using such software in general.  There is no profit motive in sight and the developers are just scratching their own itch.  Nobody is focused on growth and attracting more customers.  Instead, the software does only what it has to do with a minimum of fuss.&lt;/p&gt;
&lt;p&gt;I love that aspect, but it is also a problem.  Developers often do not care about ease of use for beginners.  Software like this is often a power tool for power users, with lots of sharp edges.  Perfect for developers, not so much for the general public.&lt;/p&gt;
&lt;p&gt;More importantly, volunteer driven FOSS has other limits.  Developer &lt;a href="https://discourse.gnome.org/t/stepping-down-as-libxml2-maintainer/31398" class="external"&gt;burn-out&lt;/a&gt; happens &lt;a href="https://jyn.dev/the-rust-project-has-a-burnout-problem/" class="external"&gt;more&lt;/a&gt; than we would like to &lt;a href="https://itsfoss.com/news/open-source-developers-are-exhausted/" class="external"&gt;admit&lt;/a&gt;, and for-profit companies tend to &lt;a href="https://thenewstack.io/ffmpeg-to-google-fund-us-or-stop-sending-bugs/" class="external"&gt;strip-mine&lt;/a&gt; the &lt;a href="https://openssf.org/blog/2025/09/23/open-infrastructure-is-not-free-a-joint-statement-on-sustainable-stewardship/" class="external"&gt;commons&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There are some solutions available for volunteer-driven projects. For example &lt;a href="https://www.clojuriststogether.org/" class="external"&gt;Clojurists together&lt;/a&gt;, &lt;a href="https://www.thanks.dev" class="external"&gt;thanks.dev&lt;/a&gt;, the &lt;a href="https://www.apache.org" class="external"&gt;Apache Foundation&lt;/a&gt;, the &lt;a href="https://sfconservancy.org" class="external"&gt;Software Freedom Conservancy&lt;/a&gt; and &lt;a href="https://nlnet.nl" class="external"&gt;NLnet&lt;/a&gt; all financially support volunteer-driven projects.  But it is not easy to apply to these, and volunteer-driven projects are often simply not organised in a way to receive money.&lt;/p&gt;&lt;a href="#conclusion"&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;With a non-profit organisation employing the maintainers of a project, there is more guarantee of continuity.  It also can ensure that the &amp;quot;boring&amp;quot; but important work gets done.  Good interface design, documentation, customer support.  All that good stuff.  If there are paying users, I expect that you get some of the benefits of corporate-driven software and less of the drawbacks.&lt;/p&gt;
&lt;p&gt;That is why I believe these types of projects will be the go-to source for sustainable, trustworthy software for end-users.  I think it is important to increase awareness about such projects.  They offer alternatives to Big Tech software that are palatable to non-technical users.&lt;/p&gt;</content>
    <id>tag:more-magic,2025-12-04:/posts/trustworthy-software-through-non-profits.html</id>
    <published>2025-12-04T05:52:32Z</published>
    <title type="text">Trustworthy software through non-profits?</title>
    <updated>2025-12-04T05:52:32Z</updated>
    <link href="https://www.more-magic.net/posts/trustworthy-software-through-non-profits.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;&lt;i&gt;NOTE: This is another guest post by &lt;a href="http://call-with-current-continuation.org/" class="external"&gt;Felix Winkelmann&lt;/a&gt;, the founder and one of the current maintainers of CHICKEN Scheme.&lt;/i&gt;&lt;/p&gt;&lt;a href="#introduction"&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Hi! This post is about a new project of mine, called &amp;quot;CRUNCH&amp;quot;, a compiler for a statically typed subset of  the programming language &lt;a href="https://www.scheme-reports.org" class="external"&gt;Scheme&lt;/a&gt;, specifically, the &lt;a href="https://r7rs.org/" class="external"&gt;R7RS (small)&lt;/a&gt; standard.&lt;/p&gt;
&lt;p&gt;The compiler runs on top of the &lt;a href="https://www.call-cc.org/" class="external"&gt;CHICKEN&lt;/a&gt; Scheme system and produces portable C99 that can then be compiled and executed on any platform that has a decent C compiler.&lt;/p&gt;
&lt;p&gt;So, why another Scheme implementation, considering that there already exists such a large number of interpreters and compilers for this language? What motivated me was the emergence of the &lt;a href="https://prescheme.org" class="external"&gt;PreScheme restoration project&lt;/a&gt;, a modernisation of &lt;a href="https://prescheme.org/papers/prescheme.pdf" class="external"&gt;&amp;quot;PreScheme&amp;quot;&lt;/a&gt;, a statically typed compiler for Scheme that is used in the &lt;a href="https://www.s48.org" class="external"&gt;Scheme48&lt;/a&gt; implementation. The original PreScheme was embedded into S48 and was used to generate the virtual machine that is targeted by the latter system. Andrew Whatson couragously started a project to port PreScheme to modern R7RS Scheme systems (PreScheme is written in Scheme, of course) with the intention of extending it and keep the quite sophisticated and interesting compiler alive.&lt;/p&gt;
&lt;p&gt;The announcement of the project and some of the reactions that it spawned made me realize that there seems to be a genuine demand for a statically typed high-performance compiler for Scheme (even if just for a subset) that would close a gap in the spectrum of Scheme systems currently available.&lt;/p&gt;
&lt;p&gt;There are compilers and interpreters for all sorts of platforms, ranging from tiny, minimal interpreters to state-of-the-art compilers, targeting about every imaginable computer system. But most Schemes need relatively complex runtime systems, have numerous dependencies, or have slow performance, which is simply due to the powerful semantics of the language: dynamic typing, automatic memory management (garbage collection), first class continuations, etc. which all have a cost in terms of overhead.&lt;/p&gt;
&lt;p&gt;What is needed is a small, portable compiler that generates more or less &amp;quot;natural&amp;quot; C code with minimal dependencies and runtime system that supports at least the basic constructs of the language and that puts an emphasis on producing efficient code, even if some of the more powerful features of Scheme are not available. Such a system would be perfect for writing games, virtual machines, or performance-sensitive libraries for other programs where you still want to use a high-level language to master the task of implementing complex algorithms, while keeping as close to C/C++ as possible. Another use is as a tool to write bare-metal code for embedded systems, device drivers and kernels for operating systems.&lt;/p&gt;
&lt;p&gt;There are some high-performance compilers like &lt;a href="https://www-sop.inria.fr/mimosa/fp/Bigloo/bigloo.html" class="external"&gt;Bigloo&lt;/a&gt; or &lt;a href="https://github.com/barak/stalin" class="external"&gt;Stalin&lt;/a&gt;. But the former still needs a non-trivial runtime-system and the latter is brittle and not actively maintained. Also, one doesn't necessarily need support for the full Scheme language and if one is willing to drop the requirement of dynamic typing, a lot of performance can be gained while still having a relatively simple compiler implementation. Even without continuations, dynamic typing, the full numeric tower and general tail call optimization, the powerful metaprogramming facilities of Scheme and the clear and simple syntax make it a useful notation for many uses that require a high level of abstraction. Using &lt;a href="https://en.wikipedia.org/wiki/Type_inference" class="external"&gt;type inference&lt;/a&gt; mostly avoids having to annotate a source program with type information and thus allows creating code which still is to a large part standard Scheme code that can (with a little care) be tested on a normal Scheme system before compiling it to more efficient native code.&lt;/p&gt;&lt;a href="#history"&gt;
&lt;h3 id="history"&gt;History&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;There was a &lt;a href="https://anonymous:@code.call-cc.org/svn/chicken-eggs/release/4/crunch/" class="external"&gt;previous extension&lt;/a&gt; for CHICKEN, also called &amp;quot;crunch&amp;quot;, that compiled to C++, used a somewhat improvised type-inferencing algorithm and was severely restricted. It was used to allow embedding statically typed code into normal CHICKEN Scheme programs. The new CRUNCH picks up this specific way of use, but is a complete reimplementation that targets C99, has a more sophisticated type system, offers some powerful optimizations and has the option to create standalone programs or separately compilable C modules.&lt;/p&gt;&lt;a href="#installation"&gt;
&lt;h3 id="installation"&gt;Installation&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;CRUNCH is only available for the new major release of CHICKEN (version 6). You will need to build and install a development snapshot containing the sources of this release, which is still unofficial and under development:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; $ wget https://code.call-cc.org/dev-snapshots/2024/12/09/chicken-6.0.0pre1.tar.gz
 $ tar xfz chicken-6.0.0pre1.tar.gz
 $ cd chicken-6.0.0pre1
 $ ./configure --prefix &amp;lt;install location&amp;gt;
 $ make
 $ make install
 $ &amp;lt;install location&amp;gt;/bin/chicken-install -test crunch&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;CHICKEN has minimal dependencies (a C compiler, &lt;tt&gt;sh(1)&lt;/tt&gt; and GNU &lt;tt&gt;make(1)&lt;/tt&gt;), so don't be put off to give it a try.&lt;/p&gt;&lt;a href="#basic-operation-and-usage"&gt;
&lt;h3 id="basic-operation-and-usage"&gt;Basic Operation and Usage&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;CRUNCH can be used as a batch compiler, translating Scheme to standalone C programs or can be used at compile time for embedded fragments of Scheme code, automatically creating the necessary glue to use the compiled code from CHICKEN Scheme. The compiler itself is also exposed as a library function, making various scenarios possible where you want to programmatically convert Scheme into native code.&lt;/p&gt;
&lt;p&gt;There are four modes of using CRUNCH:&lt;/p&gt;
&lt;p&gt;1. Embedding:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="comment"&gt;;; embed compiled code into Scheme (called using the foreign function interface):
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;import crunch&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;crunch
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;stuff arg&lt;/span&gt;)&lt;/span&gt; ...&lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;stuff 123&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;2. Standalone:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; $ cat hello.scm
 (define (main) (display &amp;quot;Hello world\n&amp;quot;))
 $ chicken-crunch hello.scm -o hello.c
 $ cc hello.c $(chicken-crunch -cflags -libs)
 $ ./a.out&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;3. Wrap compiled code in Scheme stubs to use it from CHICKEN:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; $ cat fast-stuff.scm
 (module fast-stuff (do-something)
   (import (scheme base))
   (define (do-something) ...))

 $ cat use-fast-stuff.scm
 (import fast-stuff)
 (fast-wait)

 $ chicken-crunch -emit-wrappers wrap.scm -J fast-stuff.scm -o fast-stuff.c
 $ csc -s wrap.scm fast-stuff.c -o wrap.so
 $ csc use-fast-stuff.scm -o a.out&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;4. Using CRUNCH as a library:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;#&lt;span class="comment"&gt;;1&amp;gt; (import (crunch compiler))
&lt;/span&gt;#&lt;span class="comment"&gt;;2&amp;gt; (crunch
&lt;/span&gt;       &amp;#x27;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;begin &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;main&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;display &lt;span class="string"&gt;&amp;quot;Hello world&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
       &amp;#x27;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;output-file &lt;span class="string"&gt;&amp;quot;out.c&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;a href="#module-system-and-integration-into-chicken"&gt;
&lt;h3 id="module-system-and-integration-into-chicken"&gt;Module system and integration into CHICKEN&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;CRUNCH uses the module system and syntactic metaprogramming facilities of CHICKEN. Syntax defined in CHICKEN modules can be used in CRUNCH code and vice versa. CRUNCHed code can produce &amp;quot;import libraries&amp;quot;, like in CHICKEN to provide separate compilation of modules.&lt;/p&gt;
&lt;p&gt;Modules compiled by CRUNCH may only export procedures and a standalone program is expected to export a procedure called &lt;tt&gt;main&lt;/tt&gt;. This simplifies interfacing to C and makes callbacks from C into Scheme straightforward.&lt;/p&gt;
&lt;p&gt;As in PreScheme, toplevel code is evaluated at compile time. Most assigned values can be accessed in compiled code.&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="comment"&gt;;; build a table of sine values at compile time
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; sines
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;list-&amp;gt;f64vector
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;list-tabulate 360
      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;lambda&lt;/span&gt;&lt;/i&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;n&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;sin &lt;span class="paren6"&gt;(&lt;span class="default"&gt;/ &lt;span class="paren1"&gt;(&lt;span class="default"&gt;* n π&lt;/span&gt;)&lt;/span&gt; 180&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;a href="#restrictions"&gt;
&lt;h3 id="restrictions"&gt;Restrictions&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;A number of significant restrictions apply to Scheme code compiled with CRUNCH:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No support for multiple values&lt;/li&gt;
&lt;li&gt;No support for first class continuations&lt;/li&gt;
&lt;li&gt;Tail calls can only be optimized into loops for local procedure calls or calls that can be inlined&lt;/li&gt;
&lt;li&gt;Closures (procedures capturing free variables) are not supported&lt;/li&gt;
&lt;li&gt;Procedures can have no &amp;quot;rest&amp;quot; argument&lt;/li&gt;
&lt;li&gt;Imported global variables can not be modified&lt;/li&gt;
&lt;li&gt;Currently only 2-argument arithmetic and comparison operators are supported&lt;/li&gt;
&lt;li&gt;It must be possible to eliminate all free variables via inlining and lambda-lifting&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;This list looks quite severe but it should be noted that a large amount of idiomatic Scheme code can still be compiled that way. Also, CRUNCH does not attempt to be a perfect replacement for a traditional Scheme system, it merely tries to provide an efficient programming system for domains where performance and interoperability with native code are of high importance.&lt;/p&gt;
&lt;p&gt;Datums are restricted to the following types:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;basic types: integer, float, complex, boolean, char, pointer&lt;/li&gt;
&lt;li&gt;procedure types&lt;/li&gt;
&lt;li&gt;strings&lt;/li&gt;
&lt;li&gt;vectors of any of the basic types, and vectors for specific numeric types&lt;/li&gt;
&lt;li&gt;structs and unions&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Note the absence of pairs, lists and symbols. Structures and unions are representations of the equivalent C object and can be passed by value or by pointer.&lt;/p&gt;&lt;a href="#the-runtime-system"&gt;
&lt;h3 id="the-runtime-system"&gt;The Runtime System&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;The runtime system required to run compiled code is minimal and contained in a single C header file. CRUNCH supports UNICODE and the code for UNICODE-aware case conversions and some other non-trivial operations is provided in a separate C file. UNICODE support is optional and can be disabled.&lt;/p&gt;
&lt;p&gt;No garbage collector is needed. Non-atomic data like strings and vectors are managed using reference counting without any precautions taken to avoid circular data, which is something that is unlikely to happen by accident with the data types currently supported.&lt;/p&gt;&lt;a href="#optimizations"&gt;
&lt;h3 id="optimizations"&gt;Optimizations&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;CRUNCH provides a small number of powerful optimizations to ensure decent performance and to allow more or less idiomatic Scheme code to be compiled. The type system is not fully polymorphic, but allows overloading of many standard procedures to handle generic operations that accept a number of different argument types. Additionally, a &amp;quot;monomorphization&amp;quot; optimization is provided that clones user procedures that are called with different argument types. Standard procedures that accept procedures are often expanded inline which further increases the opportunities for inlining of procedure calls - this reduces the chance of having &amp;quot;free&amp;quot; variables, which the compiler must be able to eliminate as it doesn't support closures. Aggressively moving lexically bound variables to toplevel (making them globals) can further reduce the amount of free variables.&lt;/p&gt;
&lt;p&gt;Procedures that are called only once are inlined at the call site (&amp;quot;integrated&amp;quot;). Fully general inlining is not supported, we leave that to the C compiler. Integrated procedures that call themselves recursively in tail position are turned into loops.&lt;/p&gt;
&lt;p&gt;A crucial transformation to eliminate free variables is &amp;quot;lambda lifting&amp;quot;, which passes free variables as extra arguments to procedures that do not escape and whose argument list can be modified by the compiler without interfering with user code:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;x 123&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="comment"&gt;; ... more code ...
&lt;/span&gt;  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;foo y&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;+ x y&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="comment"&gt;; ... more code ...
&lt;/span&gt;  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;foo 99&lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt;

  ~&amp;gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;x 123&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="comment"&gt;; ... more code ...
&lt;/span&gt;  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;foo y x&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;+ x y&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="comment"&gt;; ... more code ...
&lt;/span&gt;  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;foo 99 x&lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Monomorphization duplicates procedures called with arguments of (potentially) different types:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;inc x&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;+ x 1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;foo &lt;span class="paren2"&gt;(&lt;span class="default"&gt;inc 123&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;inc 99.0&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

~&amp;gt;

&lt;span class="comment"&gt;;; a &amp;quot;variant&amp;quot; represents several instantiations of the original procedure
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; inc
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;%variant
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;lambda&lt;/span&gt;&lt;/i&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;x&amp;#x27;int&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;+ x&amp;#x27;int 1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; 	&lt;span class="comment"&gt;; &amp;quot;+&amp;quot; will be specialized to integer
&lt;/span&gt;    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;lambda&lt;/span&gt;&lt;/i&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;x&amp;#x27;float&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;+ x&amp;#x27;float 1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;)	&lt;span class="comment"&gt;; ... and here to float
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;foo &lt;span class="paren2"&gt;(&lt;span class="default"&gt;inc&amp;#x27;int 123&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;inc&amp;#x27;float 99.0&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Certain higher-order primitives are expanded inline:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;vector-for-each
  v
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;lambda&lt;/span&gt;&lt;/i&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;x&lt;/span&gt;)&lt;/span&gt; ...&lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt;

~&amp;gt;   &lt;span class="comment"&gt;; (roughly)
&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; &lt;i&gt;&lt;span class="symbol"&gt;loop&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;i 0&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;unless &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&amp;gt;= i &lt;span class="paren4"&gt;(&lt;span class="default"&gt;vector-length v&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;x &lt;span class="paren6"&gt;(&lt;span class="default"&gt;vector-ref v i&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; ... &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;loop&lt;/span&gt;&lt;/i&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;+ i 1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;A final pass removes unused variables and procedure arguments and code that has no side effects and has unused results.&lt;/p&gt;
&lt;p&gt;Together these transformations can get you far enough to write relatively complex Scheme programs while ensuring the generated C code is tight, and with a little effort, easy to understand (in case you need to verify the translation) and (hopefully) does what it is intended to do.&lt;/p&gt;&lt;a href="#performance"&gt;
&lt;h3 id="performance"&gt;Performance&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Code compiled with CRUNCH should be equivalent to a straightforward translation of the Scheme code to C. Scalar values are not tagged nor boxed and are represented with the most fitting underlying C type. There is no extra overhead introduced by the translation, with the following exceptions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vector- and string accesses perform bound checks (these can be disabled)&lt;/li&gt;
&lt;li&gt;Using vectors and strings will add some reference counting overhead&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;If you study the generated code you will encounter many useless variable assignments and some unused values in statement position, these will be removed by the C compiler, also unexported procedures are declared static and so can also very often be inlined by the C compiler leading to little or no overhead.&lt;/p&gt;&lt;a href="#the-debugger"&gt;
&lt;h3 id="the-debugger"&gt;The Debugger&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;For analyzing type errors, a static debugger is included, that presents a graphical user interface. When the &lt;tt&gt;-debug&lt;/tt&gt; option is given, a &lt;a href="https://tcl.tk/" class="external"&gt;Tcl/Tk&lt;/a&gt; script is invoked in a subprocess that shows the internal node tree and can be used to examine the transformed code and the types of sub-expressions, together with the corresponding source code line (if available). Should the compilation abort with an error, the shown node-tree is the state of the program at the point where the error occurred.&lt;/p&gt;&lt;a href="#differences-to-prescheme"&gt;
&lt;h3 id="differences-to-prescheme"&gt;Differences to PreScheme&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;CRUNCH is inspired by and very similar to PreScheme, but has a number of noteworthy differences. CRUNCH tries to be as conformant to R7RS (small) as possible and handles UNICODE characters and strings. It also is tightly integrated into CHICKEN, allowing nearly seamless embedding of high-performance code sections. Macros and top-level code can take full advantage of the full CHICKEN Scheme language and its ecosystem of extension libraries.&lt;/p&gt;
&lt;p&gt;PreScheme supports multiple values, while CRUNCH currently does not.&lt;/p&gt;
&lt;p&gt;PreScheme uses explicit allocation and deallocation for compound data objects, while CRUNCH utilizes reference counting, removing the need to manually clean up resources.&lt;/p&gt;
&lt;p&gt;I'm not too familiar with the PreScheme compiler itself, but I assume it provides more sophisticated optimizations, as it does convert to Static Single Assignment form (SSA), so it is to be expected that the effort to optimise the code is quite high. On the other hand, modern C compilers already provide a multitude of powerful optimizations, so it is not clear how many advantages lower-level optimizations will bring.&lt;/p&gt;&lt;a href="#future-plans"&gt;
&lt;h3 id="future-plans"&gt;Future Plans&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;There is a lot of room for improvements. Support of multiple vales would be nice, and not too hard to implement, but will need to follow a convention that should not be too awkward to use on the C side. Also, the support for optional arguments is currently quite weak; the ability to specify default values is something that needs to be added.&lt;/p&gt;
&lt;p&gt;Primitives for many POSIX libc system calls and library functions should be straightforward to use in CRUNCH code, at least the operations provided by the &lt;tt&gt;(chicken file posix)&lt;/tt&gt; module.&lt;/p&gt;
&lt;p&gt;What would be particularly nice would be if the compiler detects state machines - mutually recursive procedures that call each other in tail position.&lt;/p&gt;
&lt;p&gt;Other targets are possible, like GPUs. I don't know anything about that, so if you are interested and think you can contribute, please don't hesitate to contact me.&lt;/p&gt;&lt;a href="#disclaimer"&gt;
&lt;h3 id="disclaimer"&gt;Disclaimer&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;CRUNCH is currently alpha-software. It certainly contains numerous bugs and shortcomings that will hopefully be found and corrected as the compiler is used. If you are interested, I invite you to give it a try. Contact &lt;a href="http://call-with-current-continuation.org/me.html" class="external"&gt;me&lt;/a&gt; directly or join the &lt;tt&gt;#chicken&lt;/tt&gt; IRC channel on &lt;a href="https://libera.chat" class="external"&gt;Libera.chat&lt;/a&gt;, if you have questions, want to report bugs, if you would like to suggest improvements or if you just want to know more about it.&lt;/p&gt;
&lt;p&gt;All feedback is very welcome!&lt;/p&gt;&lt;a href="#links"&gt;
&lt;h3 id="links"&gt;Links&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;The &lt;a href="http://wiki.call-cc.org/eggref/6/crunch" class="external"&gt;CRUNCH manual&lt;/a&gt; can be found at the CHICKEN wiki, the source code repository is &lt;a href="https://anonymous@code.call-cc.org/svn/chicken-eggs/release/6/crunch/" class="external"&gt;here&lt;/a&gt;.&lt;/p&gt;</content>
    <id>tag:more-magic,2024-12-16:/posts/crunch.html</id>
    <published>2024-12-16T12:44:16Z</published>
    <title type="text">Let's CRUNCH!</title>
    <updated>2024-12-16T12:44:16Z</updated>
    <link href="https://www.more-magic.net/posts/crunch.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;&lt;i&gt;NOTE: This is a guest post by &lt;a href="http://call-with-current-continuation.org/" class="external"&gt;Felix Winkelmann&lt;/a&gt;, the founder and one of the current maintainers of CHICKEN Scheme.&lt;/i&gt;&lt;/p&gt;&lt;a href="#introduction"&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;This article is about the changes in the next major version of &lt;a href="https://www.call-cc.org/" class="external"&gt;CHICKEN Scheme&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The current version is 5.4.0.  The next major version, 6.0.0, is mostly implemented.  Currently we are adding final touches before preparing the next release.  If you are already familiar with CHICKEN, this article will help you get a more detailed view of what has been done. If you are not into CHICKEN or even Scheme, this article may still give you an insight into what's involved in the development and maintenance of a programming language project.  You may also find it interesting to know how we address issues like portability and backwards-compatibility.  There are also some juicy details on implementation techniques.&lt;/p&gt;
&lt;p&gt;No previous knowledge of CHICKEN Scheme is required, but it will help if you are familiar with common terms used in programming language design and Lisp-y languages.&lt;/p&gt;&lt;a href="#versions"&gt;
&lt;h2 id="versions"&gt;Versions&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;CHICKEN uses the usual &lt;tt&gt;major.minor.patch&lt;/tt&gt; versioning scheme, where we bump major versions only for significant changes that break compatibility with older versions. CHICKEN has a relatively large community for a non-mainstream language and has lots of contributed extension libraries called &amp;quot;eggs&amp;quot;.  Breaking backwards compatibility in non-major versions adds implementation effort for users that just want keep their CHICKEN up to date and any eggs they're using should also keep working.&lt;/p&gt;
&lt;p&gt;The process of avoiding breakage can sometimes become challenging.  We may, for example, provide two different implementations for one and the same thing, to allow adoption of the new feature while keeping old code working.  Typically this happens when the new feature is safer, easier to use, faster or more standards compliant than the old.  We also remove features in stages.  First we mark it as deprecated, and delete it later.  This allows users to upgrade their code gradually.&lt;/p&gt;
&lt;p&gt;On major version changes, we create a new mirror of the egg &amp;quot;repository&amp;quot;, where most of the extensions are stored. Externally contributed eggs can choose when and how to publish an extension for specific versions.  This is described in &lt;a href="/posts/vcs-independent-distribution.html" class="internal"&gt;a previous post on this blog&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Major version changes also usually bump the &amp;quot;binary version&amp;quot;.  This is a suffix to the shared runtime library name to avoid intermixing tools and programs written for one version with the libraries for another.&lt;/p&gt;
&lt;p&gt;We started CHICKEN major version 6 to introduce new features that were dearly required but were impossible to add without changing external interfaces, in particular what modules exist and what they export. Specifically, we needed full support for UNICODE strings and compliance with the &lt;a href="https://r7rs.org/" class="external"&gt;R7RS (small)&lt;/a&gt; language standard.&lt;/p&gt;
&lt;p&gt;Both features were already available in a rudimentary manner as external libraries.  They were not fully integrated, a fact that showed in various places and could lead to subtle bugs as core and extension code assumed differences in string representation and the behaviour of standard procedures. The same approach was used for integrating the &amp;quot;full numeric tower&amp;quot; (the full set of numeric types, including rationals, big integers and complex numbers), which was formerly a library and was moved into the core system with the 5.0.0 release.&lt;/p&gt;
&lt;p&gt;We'll now describe the most noteworthy changes made during this major version transition.&lt;/p&gt;&lt;a href="#unicode"&gt;
&lt;h2 id="unicode"&gt;UNICODE&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;A major shortcoming of CHICKEN up to now was that it didn't support full UNICODE strings.  All string data was assumed to consist of 8-bit characters in the ASCII or Latin-1 range. Internationalisation of source code and applications is unavoidable and libraries and operating systems have moved towards UTF-8 as a standard character encoding.  So we saw no choice but to find a reasonably efficient way of using the full range of possible characters in all parts of the system.&lt;/p&gt;
&lt;p&gt;There is an open-ended space of design choices regarding how to efficiently implement UNICODE strings.  The Damocles Sword of unanticipated performance degradation constantly looms over the head of the language implementer, so finding the ideal solution in terms of memory use, speed and simplicity is not easy.  Some implementations go to great lengths by providing complex storage schemes or multiple representations depending on a strings' content.  In the end, we think a simple representation serves everybody better by being easier to understand and maintain.&lt;/p&gt;
&lt;p&gt;Also it is not entirely sure that (say) a dynamic multi-representation approach pays off sufficiently.  Too many factors come into play, like string usage patterns in applications, memory management and implementation overhead.  Data exchange at the boundaries of operating system and foreign code also have to be taken into account. You want to avoid unnecessary conversions and copying, especially because CHICKEN is geared towards easy interfacing to external libraries and OS functionality.&lt;/p&gt;
&lt;p&gt;We decided to use an UTF-8 representation internally.  Many operating systems and applications already support UTF-8, which removes the need for costly conversions.  UTF-8 is also backwards compatible to ASCII and keeps storage requirements at a minimum.&lt;/p&gt;
&lt;p&gt;Since UTF-8 is a multi-byte encoding, character lookup in a string is of linear complexity.  Characters have to be scanned when addressing a specific index in a string.  To avoid repeatedly scanning the same section of a string when iterating over it, we use a simple cache slot in the string that maps byte-offsets to code point indices and holds the offset/index pair of the last access.&lt;/p&gt;&lt;a href="#string-representation"&gt;
&lt;h3 id="string-representation"&gt;String representation&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;A quick recap regarding how strings are currently stored in CHICKEN is in order.  If you are interested, there's also an older post on this blog with a more detailed &lt;a href="/posts/internals-data-representation.html" class="internal"&gt;explanation of the data representation&lt;/a&gt; used by CHICKEN.&lt;/p&gt;
&lt;p&gt;Characters are stored as immediates with the special bit pattern &lt;tt&gt;1110&lt;/tt&gt; (type code 111):&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/characters.svg" /&gt;&lt;/p&gt;
&lt;p&gt;This gives us enough bits (even on 32-bit platforms) to hold all code points in the Basic Multilingual Plane (code points in the range 32 - 0x1fffff).  CHICKEN 5 already supported characters in that range, but strings were still restricted to having 8-bit elements.&lt;/p&gt;
&lt;p&gt;Up to CHICKEN 5 a string was represented by a single byteblock:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/direct-string-representation.svg" /&gt;&lt;/p&gt;
&lt;p&gt;In CHICKEN 6 we add an indirection:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/indirect-bytevector-string-representation.svg" /&gt;&lt;/p&gt;
&lt;p&gt;As you can see, the string itself is a normal block containing a pointer to a byteblock holding the UTF-8 byte sequence and a trailing zero byte.  The &amp;quot;Count&amp;quot; slot is a fixnum with the number of code points in the string (the length).  &amp;quot;Offset&amp;quot; and &amp;quot;Index&amp;quot; act as a cache for the byte-offset and code point-index of the last access.  They are reset to zero if the string changes its length due to a character's width changing at an offset before the cached point.&lt;/p&gt;
&lt;p&gt;An indirection is necessary regardless of the other details of the representation: as UTF-8 is a multi-byte encoding, destructively modifying characters in a string may grow or shrink the total byte-sequence.  The string must still keep its identity and be indistinguishable from the original string (in terms of the primitive &lt;tt&gt;eq?&lt;/tt&gt; procedure).&lt;/p&gt;
&lt;p&gt;One obvious optimisation we can do here is that character accesses for strings where the length (&amp;quot;Count&amp;quot;) and the length of the character data (encoded in the header of the byteblock) minus one is equal: then we can simply index by byte offset.&lt;/p&gt;
&lt;p&gt;Alternative representations are possible.  I believe the following is used in &lt;a href="https://synthcode.com/scheme/chibi" class="external"&gt;Chibi Scheme&lt;/a&gt;: keep a list of &amp;quot;chunks&amp;quot;, i.e. multiple byte-offset/code point-index pairs per string. You can traverse this list to obtain the first chunk of string data containing the index you want to access.&lt;/p&gt;
&lt;p&gt;In CHICKEN this would probably be represented thus:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/alternative-chunked-string-representation.svg" /&gt;&lt;/p&gt;
&lt;p&gt;This way we can find the offset for the index right at or before the location addressed.  This reduces the amount of scanning to the part inside a chunk pointed to by the offset/index pair.&lt;/p&gt;
&lt;p&gt;Such an approach of maintaining the offset/index list is more complex and keeping it up to date is more effort than the simple offset/index cache. Should the performance impact of the simpler representation turn out to be too large, the alternative approach may still be an option to try.&lt;/p&gt;
&lt;p&gt;This leads me to the subject of benchmarks.  We do have a benchmark suite holding a number of micro-benchmarks and CHICKEN 6 has been compared to previous versions using this suite.  Nevertheless, the results of micro-benchmarking have to be taken with a grain of salt.&lt;/p&gt;
&lt;p&gt;The behaviour of real-world applications may differ considerably depending on the memory consumption, memory address patterns and the type and amount of data processed.  Reasoning about performance is especially difficult due to the complex caching mechanisms of contemporary hardware and operating systems. Therefore we will try to use the simplest approach that has a good chance of providing sufficient performance while keeping the implementation effort and complexity at a minimum.&lt;/p&gt;&lt;a href="#dealing-with-the-outside-world"&gt;
&lt;h3 id="dealing-with-the-outside-world"&gt;Dealing with the outside world&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;There's another point we have to address when considering strings that are received from external sources like OS APIs, from files and from the foreign function interface.  What to do when encountering invalid UTF-8 byte sequences, for example when reading file or directory names?  Signal an error?  Convert to some other representation or mark the location in the byte sequence using some special pattern?&lt;/p&gt;
&lt;p&gt;We decided to basically ignore the problem.  Strings are accepted whether valid or not.  Only when decoding a string we distinguish between valid and invalid sequences.  When indexing and scanning a string's byte sequence, we return the invalid byte as a &amp;quot;surrogate pair end&amp;quot; code point that has the value &lt;tt&gt;0xDCxx&lt;/tt&gt;. This approach allows us to store the byte in the lower 8 bits of the code point. When inserting a character in a string that has such a value, we simply copy the byte. As I understand it, this is the approach used by the &amp;quot;surrogateescape&amp;quot; error handler in &lt;a href="https://peps.python.org/pep-0383/" class="external"&gt;PEP 383&lt;/a&gt;. However, we do this masking &lt;i&gt;every time&lt;/i&gt; we decode an unexpected byte (and do the inverse when encoding).&lt;/p&gt;
&lt;p&gt;Say we received a string from an external source containing the following byte sequence:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/invalid-utf8-plain.svg" /&gt;&lt;/p&gt;
&lt;p&gt;This is invalid UTF-8. Extracting character by character with the described method would yield the following code point values:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/invalid-utf8-extracted.svg" /&gt;&lt;/p&gt;
&lt;p&gt;Inserting such a surrogate pair end code point will inject the value of the lower byte.  For example, calling &lt;tt&gt;(string-set! str #\xdcfe)&lt;/tt&gt;, where &lt;tt&gt;str&lt;/tt&gt; is the above invalid utf-8 encoded string would yield the following byte sequence:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/invalid-utf8-inserting.svg" /&gt;&lt;/p&gt;
&lt;p&gt;The advantage is that we can simply accept and pass strings containing invalid sequences as if nothing happened.  We don't need to do any conversions and checks. We can also access items in the character sequence and store them back without having to worry about the validity of the sequence with respect to the UTF-8 encoding.  The process is &amp;quot;lossless&amp;quot;.&lt;/p&gt;
&lt;p&gt;The disadvantage is that we have to perform an additional check when encoding or decoding UTF-8 sequences. Again we decided to reduce copying and transcoding overhead and rather have complete transparency regardless of the source of the string.  Furthermore no validation is performed for incoming strings. The R7RS standard procedure &lt;tt&gt;utf8-&amp;gt;string&lt;/tt&gt; which converts bytevectors into strings does validation, though to at least ensure that strings created from binary data are always correctly encoded.&lt;/p&gt;
&lt;p&gt;A final issue is UNICODE handling on Windows platforms.  There, the OS API entry-points that are UNICODE aware use UTF-16 for strings like filenames or the values of environment variables.  On Windows there is no choice but to encode and decode from UTF-8 to UTF-16 and back when interfacing with the OS.&lt;/p&gt;&lt;a href="#port-encodings"&gt;
&lt;h2 id="port-encodings"&gt;Port encodings&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;When accessing files, we still want to be able to read and write data in an 8-bit encoding or in binary.  We may also want to support additional encodings, even though these are currently not provided by default so we'll need to associate an &amp;quot;encoding&amp;quot; property to &amp;quot;ports&amp;quot;.  Ports are the Scheme objects that provide access to files and other streams of data, like traffic received from a network.  The encoding is selected when opening a port using additional arguments to standard procedures that create ports for textual input and output like &lt;tt&gt;open-input-port&lt;/tt&gt;/&lt;tt&gt;open-output-port&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Ports internally hold a table of &amp;quot;port methods&amp;quot;, roughly similar to how object-oriented programming systems attach behaviour to data objects of a particular class. The port methods in former versions of CHICKEN included the low-level counterpart of the &lt;a href="https://wiki.call-cc.org/man/6/Module%20(scheme%20base)#input" class="external"&gt;standard operations &lt;tt&gt;peek-char&lt;/tt&gt;, &lt;tt&gt;read-char&lt;/tt&gt; and &lt;tt&gt;read-string&lt;/tt&gt;&lt;/a&gt; for input ports and &lt;a href="https://wiki.call-cc.org/man/6/Module%20(scheme%20base)#output" class="external"&gt;&lt;tt&gt;write-char&lt;/tt&gt;/&lt;tt&gt;write-string&lt;/tt&gt; (among others)&lt;/a&gt; for output ports.  The major change here is to replace the string I/O methods with methods that act upon bytevectors.&lt;/p&gt;
&lt;p&gt;An internal mechanism delegates the operations for encoding and decoding or scanning for the next character in a stream to an internal hook procedure.  Additional encodings can be registered by using a built-in procedure to extend the hook.  Currently supported are binary, UTF-8 and Latin-1 encodings.  Support for a larger set of encodings can be done through extensions and thus can be developed separately from the core system.  Port encodings can be accessed using &lt;tt&gt;port-encoding&lt;/tt&gt;.  They can also be changed using the SRFI-17 setter for &lt;tt&gt;port-encoding&lt;/tt&gt;, because encodings need sometimes to be changed while the port is still open.&lt;/p&gt;
&lt;p&gt;R7RS does not define whether binary I/O standard procedures are allowed to operate on textual ports and vice versa.  In CHICKEN we do not restrict the set of operations depending on the port type, so you can read and write bytevectors to and from a textual port and the other way round.  We think this is more practical and intuitive - it makes more sense to read and write binary data as bytevectors and have dedicated operations for this.&lt;/p&gt;&lt;a href="#r7rs-support"&gt;
&lt;h2 id="r7rs-support"&gt;R7RS support&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;The second big change for CHICKEN 6 is proper R7RS (small) compliance. Like with the UTF-8 support this was previously provided by an extension library, but using it needed some minor extra steps to set up. Now, all syntactic definitions of &lt;a href="https://wiki.call-cc.org/man/6/Module%20(scheme%20base)" class="external"&gt;the &lt;tt&gt;(scheme base)&lt;/tt&gt; module&lt;/a&gt; are available by default (most notably &lt;a href="https://wiki.call-cc.org/man/6/Module%20(scheme%20base)#library-syntax" class="external"&gt;&lt;tt&gt;define-library&lt;/tt&gt;&lt;/a&gt;) without requiring any further action.&lt;/p&gt;
&lt;p&gt;Deciding what is available by default in a compilation unit or interpretation environment is a bit of a problem: to make it easy to get going when experimenting or scripting, we defaulted to having all standard R5RS procedures and macros available in the base environment of the interpreter (&lt;tt&gt;csi&lt;/tt&gt;), together with the imports from the &lt;tt&gt;(chicken base)&lt;/tt&gt; module.  Compiled code was slightly more restricted but defaulted also to R5RS.&lt;/p&gt;
&lt;p&gt;In CHICKEN 5 the &lt;tt&gt;scheme&lt;/tt&gt; module referred to the R5RS standard procedures.  To avoid breaking too much existing code this is still the case.  So now, &lt;tt&gt;scheme&lt;/tt&gt; is an alias for the R7RS &lt;tt&gt;(scheme r5rs)&lt;/tt&gt; library module that exports all bindings of the former language standard.  But to avoid duplicating the set of exported identifiers over several core modules, certain functionality has been moved from &lt;tt&gt;(chicken base)&lt;/tt&gt; to &lt;tt&gt;(scheme base)&lt;/tt&gt; and is thus not available in the default toplevel environment.&lt;/p&gt;
&lt;p&gt;To make a long story short, the switch makes it necessary to access certain standard bindings like &lt;tt&gt;open-input-string&lt;/tt&gt; by importing additional modules like &lt;tt&gt;(scheme base)&lt;/tt&gt;. This is not necessarily a bad thing, as it incentivises the user to write code in a more standard compliant way.  But it all feels a bit clunky and may have been a suboptimal choice.  Note that just adding an &lt;tt&gt;(import (scheme base))&lt;/tt&gt; is usually enough to make existing code run.  We will see how that works out.&lt;/p&gt;
&lt;p&gt;All required &lt;tt&gt;(scheme ...)&lt;/tt&gt; modules are implemented and can be imported using their full functionality.  Two notable changes that influence backwards compatibility are generative record types and hexadecimal escape sequences in string literals.&lt;/p&gt;
&lt;p&gt;Formerly record types defined with &lt;tt&gt;define-record-type&lt;/tt&gt; were non-generative: re-defining a record type with the same name, even if the type definition is completely different, would not create a new type.  Instances of the former definition would also be of the newly defined type, provided the type name is the same.  Now every definition of a record type creates a completely new type, regardless of the name.  This is of course more correct and much safer as it doesn't invalidate previously defined instances.&lt;/p&gt;
&lt;p&gt;A second (and much more annoying) change is that R7RS requires hex escape sequences in string literals to be terminated by a semicolon. Unfortunately the change is incompatible to the convention used in most programming languages, including existing many Lisp and Scheme implementations.&lt;/p&gt;
&lt;p&gt;What in CHICKEN 5 would looked like this:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;   &amp;quot;the color \x1b[31mRED\x1b[0m&amp;quot;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;in CHICKEN 6 (and R7RS) must now be (note the semicolon):&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;   &amp;quot;the color \x1b;[31mRED\x1b;[0m&amp;quot;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The motivation here was probably to avoid having dedicated escape sequences for values that require more than 2 hex digits (e.g. &lt;tt&gt;\uNNNN&lt;/tt&gt;).  The change is particularly bad from a compatibility point of view.  All string literals that contain the old style of escape sequences must be changed.  To keep code working in both CHICKEN 5 and 6 you can use the 4-digit &lt;tt&gt;\uNNNN&lt;/tt&gt; escape sequence which is still valid in all versions.&lt;/p&gt;&lt;a href="#foreign-function-interface-changes"&gt;
&lt;h2 id="foreign-function-interface-changes"&gt;Foreign Function Interface changes&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;CHICKEN has a very easy to use foreign function interface, which mostly derives from the fact that the compiler generates C.  The alternative approach are binary FFIs that use native code to interface with C code, like &lt;a href="https://github.com/libffi/libffi" class="external"&gt;libffi&lt;/a&gt;, which must reproduce a lot of ABI details to safely interface with C libraries, things like struct alignment and padding, how arguments of various lengths are passed on the stack, etc.&lt;/p&gt;
&lt;p&gt;The most notable FFI-related change for CHICKEN 6 is that it allows passing and returning C structs and unions to and from foreign code by value.  The contents are copied in and out of bytevectors and wrapped in a block.  The components of the struct or union can not be directly manipulated in Scheme but can be passed on to other foreign functions.  Additionally, for completeness, you can now also directly pass C99 &lt;tt&gt;complex&lt;/tt&gt; numbers. Note that complex numbers in the FFI are always passed as inexact (i.e., floating-point), as opposed to Scheme complex numbers that may have exact (integer or even rational) real and imaginary components.&lt;/p&gt;&lt;a href="#platform-support-and-build-system"&gt;
&lt;h2 id="platform-support-and-build-system"&gt;Platform support and build system&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Here two major changes have been introduced.  First, we now have a proper configuration (&amp;quot;&lt;tt&gt;configure&lt;/tt&gt;&amp;quot;) script. Formerly, all build parameters were passed as extra arguments to &lt;tt&gt;make(1)&lt;/tt&gt;, like this:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;   make PREFIX=$HOME/.local ...&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This required that for every &lt;tt&gt;make(1)&lt;/tt&gt; invocation, the same set of parameters had to be given to avoid inconsistencies.  A configuration script written in portable POSIX &lt;tt&gt;sh(1)&lt;/tt&gt; notation is now provided to perform the configuration step once before building. It also follows the de facto convention used in many GNU programs, where the usual incantation is:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;   ./configure; make; make install&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Note that we don't use the dreaded &amp;quot;autotools&amp;quot; (&lt;tt&gt;autoconf&lt;/tt&gt;, &lt;tt&gt;automake&lt;/tt&gt; and &lt;tt&gt;libtool&lt;/tt&gt;), which have arcane syntax, are very brittle and produce more problems that they are trying to solve. They were originally designed to port code to now dead or obscure UNIX derivatives, yet fail to provide a straightforward and easy to use configuration tool for modern systems (Linux/BSD, Mac, Windows, mostly). Our &lt;tt&gt;configure&lt;/tt&gt; script is hand written instead of auto-generated, and only checks for the platform differences that are relevant to those platforms that CHICKEN actually supports.&lt;/p&gt;
&lt;p&gt;The old style of passing variables to &lt;tt&gt;make(1)&lt;/tt&gt; should still work, but is deprecated.&lt;/p&gt;
&lt;p&gt;The second change in the build system is that we cleaned up the confusion about toolchains on Windows systems. There is a bunch of half-maintained flavors of GNU-based C development environments for Windows systems (&amp;quot;MingGW&amp;quot;, &amp;quot;MingGW-w64&amp;quot;, &amp;quot;MSYS2&amp;quot;, etc.) and it is a constant source of pain to support and test all these variants.&lt;/p&gt;
&lt;p&gt;There is now one official &amp;quot;blessed&amp;quot; toolchain that we support. Specifically, we recommend Chris Wellon's excellent &lt;a href="https://github.com/skeeto/w64devkit" class="external"&gt;w64devkit&lt;/a&gt;.  It contains compilers, build tools and enough of a POSIX environment for building CHICKEN on Windows.  We also require a POSIX &lt;tt&gt;sh(1)&lt;/tt&gt; (contained in w64devkit) and have dropped all support for building on a non-POSIX shell, i.e. &lt;tt&gt;cmd.exe&lt;/tt&gt;.  This simplifies the build and package management tools considerably.  It also ensures we have less environments to test.&lt;/p&gt;
&lt;p&gt;Building for Windows Subsystem for Linux (WSL) and Cygwin is of course still supported, but those use the UNIX build setup and need no or very little specific platform support.&lt;/p&gt;&lt;a href="#minor-changes"&gt;
&lt;h2 id="minor-changes"&gt;Minor changes&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Quite a number of minor changes have taken place that either increase the robustness or standards compliance of the system.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://wiki.call-cc.org/man/6/Module%20(scheme%20base)#signaling-errors-in-macro-transformers" class="external"&gt;&lt;tt&gt;syntax-error&lt;/tt&gt;&lt;/a&gt; is now a macro, as required by R7RS.  Previously there was a &lt;a href="https://wiki.call-cc.org/man/5/Module%20(chicken%20syntax)#syntax-error" class="external"&gt;&lt;tt&gt;syntax-error&lt;/tt&gt;&lt;/a&gt; procedure in &lt;tt&gt;(chicken syntax)&lt;/tt&gt; with the same argument signature. So where the error was previously raised at runtime, it is now done at expansion time.  This is something to take note of when porting code to CHICKEN 6.  The invocation is still the same, so the difference can at least be identified easily and corrected, and &lt;tt&gt;(scheme base)&lt;/tt&gt; needs to be imported, of course.&lt;/p&gt;
&lt;p&gt;The &lt;tt&gt;csc&lt;/tt&gt; compiler driver passes arguments now properly to subprocesses via &lt;tt&gt;execve(2)&lt;/tt&gt; and not &lt;tt&gt;system(3)&lt;/tt&gt; which reduces shell quoting headaches.&lt;/p&gt;
&lt;p&gt;The &lt;tt&gt;chicken-install&lt;/tt&gt; package (&amp;quot;egg&amp;quot;) manager locks the build cache directory to avoid conflicts when running multiple installations in parallel.  Also, a &lt;tt&gt;custom-config&lt;/tt&gt; feature has been added to places in the package description (&lt;tt&gt;.egg&lt;/tt&gt;) file that specify compile and link options provided by external tools like &lt;tt&gt;pkg-config&lt;/tt&gt; for more portable configuration of native libraries that packages use.  The configuration script is expected to be Scheme code.  Other eggs can extend the set of possible customisation facilities by providing library code to access them.&lt;/p&gt;
&lt;p&gt;The &lt;tt&gt;feathers&lt;/tt&gt; debugger has been removed from the core system and re-packaged as an egg, allowing separate development or replacement. It always was a bit of a proof-of-concept thing that lacks the robustness and flexibility of a real debugger.  Some users found it helpful, so we keep it for the time being.&lt;/p&gt;&lt;a href="#future-directions"&gt;
&lt;h2 id="future-directions"&gt;Future directions&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Every major release is a chance of fixing long-standing problems with the codebase and address bad design decisions. CHICKEN is now nearly 25 years old and we had many major overhauls of the system.  Sometimes these caused a lot of pain, but still we always try to improve things and hopefully make it more enjoyable and practical for our users. There are places in the code that are messy, too complex, or that require cleanup or rewrite, always sitting there waiting to be addressed.  On the other hand CHICKEN has been relatively stable compared to many other language implementations and has a priceless community of users that help us improving it.  Our users never stop reminding us of what could be better, where the shortcomings are, where things are hard to use or inefficient.&lt;/p&gt;
&lt;p&gt;So the final goal is and will always be to make it more robust and easier to use.  Performance improvements are always good but are secondary.  Strong standards compliance is a requirement, unless it interferes with practicality.  We also try to avoid dependencies in the core system at all costs.  This eases porting and avoids friction that is very often introduced by inadequate tools or overdesigned development environments.&lt;/p&gt;&lt;a href="#some-moody-ramblings-about-scheme-standards"&gt;
&lt;h3 id="some-moody-ramblings-about-scheme-standards"&gt;Some moody ramblings about Scheme standards&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;The switch to seamless support for R7RS (small) was due for quite a while.  R7RS is by now the generally accepted Scheme standard that implementations try to follow.  How the further development of R7RS (large) will turn out remains to be seen, but I'm not very confident that it will result in anything more that just a shapeless agglomeration of features. The current direction seems to be oriented towards creating something that includes everything but the &amp;quot;kitchen-sink&amp;quot; - too ambitious and too much driven by the urge to produce something big and comprehensive.&lt;/p&gt;
&lt;p&gt;What always distinguished Scheme from other languages and Lisp dialects was its elegance and minimalism.  This resulted in a large number of experimental implementations, the investigation of various directions of programming language semantics and in highly interesting advanced implementation techniques that are still in use today.  The expressiveness and the small number of core concepts made it also perfect for teaching computing.  It still is great for teaching, even if the tendency to address perceived requirements of the &amp;quot;market&amp;quot; replaces the academic use of Scheme with languages that belong more to the &amp;quot;mainstream&amp;quot;.  This strikes me as strange, as if learning multiple languages and studying different programming paradigms couldn't help in obtaining a broader view of software development; or as if one is somehow wasting time by exploring the world of programming in a non-mainstream language.&lt;/p&gt;
&lt;p&gt;Repeatedly the small size and limited scope of Scheme has driven a number of enthusiasts dedicated to favouring a broader use in the industry to demand &amp;quot;bigness&amp;quot;.  They dream of a comprehensive standard that will support everything and please everyone and makes it easy to write portable and non-trivial applications in Scheme and have them run on large number of implementations.  With this comes the tacit expectation that implementers will just follow such a large standard and implement it faithfully.&lt;/p&gt;
&lt;p&gt;But what made Scheme successful (and beautiful) was the small size, the small number of powerful concepts, the minimalism, the joy in experimentation.  Trying to create the Comprehensive Mother of all Schemes is in my opinion a waste of time.  In fact, it makes Scheme &lt;i&gt;less&lt;/i&gt; relevant.  Large languages inevitably die - the warts and inconsistencies that crop up when you try to design too much up front will just get more blatant as the language ages and will annoy users, constrain implementers and make people search for alternatives.&lt;/p&gt;
&lt;p&gt;You can already write serious programs and use a large number of libraries in Scheme: just install CHICKEN, Guile or (even) Racket and get going.  The code will to a certain part not be portable across implementations, that's unavoidable, but to use dynamic languages effectively and successfully, some experience with and a certain understanding of the design of the underlying compiler or interpreter is necessary anyway.&lt;/p&gt;&lt;a href="#acknowledgements"&gt;
&lt;h2 id="acknowledgements"&gt;Acknowledgements&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;I would like to thank my employer, &lt;a href="https://www.bevuta.com" class="external"&gt;bevuta IT GmbH&lt;/a&gt; which sponsored part of the effort of preparing a new major release of CHICKEN.&lt;/p&gt;</content>
    <id>tag:more-magic,2024-11-18:/posts/chicken-6.html</id>
    <published>2024-11-18T14:27:11Z</published>
    <title type="text">What to expect from CHICKEN 6</title>
    <updated>2024-11-18T14:27:11Z</updated>
    <link href="https://www.more-magic.net/posts/chicken-6.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;Recently, a user was asking on IRC why CHICKEN doesn't give proper line numbers for error call traces in the interpreter.  This is indeed rather odd, because the compiler gives numbered traces just fine.&lt;/p&gt;
&lt;p&gt;After a brief discussion, we figured that this was probably because line numbers are stored in a &amp;quot;database&amp;quot; (hash table) which maps the source expression to a line number.  Because you can keep calling &lt;tt&gt;(eval)&lt;/tt&gt; with fresh input, the number of expressions evaluated is potentially infinite.&lt;/p&gt;
&lt;p&gt;This would lead to unbounded growth of the line number database, eventually eating up all available memory.&lt;/p&gt;
&lt;p&gt;We'd like to fix this.  A great solution for this problem would be &lt;i&gt;weak references&lt;/i&gt;.  A weak reference is a reference to a value that does &lt;i&gt;not&lt;/i&gt; cause the garbage collector to hold on to that value.  If other things still refer to the value, it is preserved and the weak reference is maintained.  If &lt;i&gt;only&lt;/i&gt; weak references refer to a value, it may be collected.&lt;/p&gt;
&lt;p&gt;The line number database could then consist of such weak references to source expressions.  If an expression is no longer held onto, it can be collected and the line number eventually removed.  This would turn the database from a regular hash table into a &lt;i&gt;weak hash table&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;This requires hooking into the garbage collector so that it knows about these references and can drop them.  Since our collector is a &lt;i&gt;copying&lt;/i&gt; collector, addresses of objects change over time, and a weak reference needs to be updated if something is still hanging onto it, without itself causing the weakly held object to stick around.&lt;/p&gt;&lt;a href="#a-quick-recap-of-garbage-collection"&gt;
&lt;h2 id="a-quick-recap-of-garbage-collection"&gt;A quick recap of garbage collection&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;To explain how we changed our garbage collector, I will start with a quick high-level recap of how the garbage collection works.  I'll explain just enough to cover what is needed to understand weak references.  For a more in-depth look at CHICKEN's garbage collection, see &lt;a href="/posts/internals-gc.html" class="internal"&gt;my post on the GC&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First, we have to realise that CHICKEN stores all its values in a machine word.  It distinguishes between &amp;quot;immediate&amp;quot; values and non-immediate or &amp;quot;block&amp;quot; values.  Immediate values can be either fixnums (bit 0 is set) or other &amp;quot;small&amp;quot; values (bit 1 is set). Non-immediates are recognised because the lower two bits are zero, which is very convenient, as a &lt;i&gt;pointer&lt;/i&gt; to a word-aligned address happens to have the lower two bits cleared as well!&lt;/p&gt;
&lt;p&gt;In other words, non-immediate values are simply C pointers, whereas the immediate values are encoded long integers.  So, non-immediates are allocated in memory and represented by a pointer to them.  At the pointer's address we find a &lt;i&gt;header&lt;/i&gt; which encodes what exactly is stored there, and (optionally) the &lt;i&gt;data&lt;/i&gt;, where we store the contents of compound objects.&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;  &lt;span class="symbol"&gt;typedef&lt;/span&gt; &lt;span class="symbol"&gt;struct&lt;/span&gt;
  &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
    C_word header;
    C_word data&lt;span class="paren2"&gt;[&lt;span class="default"&gt;&lt;/span&gt;]&lt;/span&gt;;    &lt;span class="comment"&gt;/* Variable-length array: header determines length */&lt;/span&gt;
  &lt;/span&gt;}&lt;/span&gt; C_SCHEME_BLOCK;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;In typical Scheme objects, the &lt;tt&gt;data&lt;/tt&gt; consists of &lt;i&gt;slots&lt;/i&gt;.  For example, the &lt;tt&gt;car&lt;/tt&gt; and the &lt;tt&gt;cdr&lt;/tt&gt; of a pair are slots, the elements of a vector are slots, etc.  Each slot contains a Scheme value.  In a graphical representation, a block object looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/header-and-data.svg" /&gt;&lt;/p&gt;
&lt;p&gt;The data representation will be important to understand how we implement weak pairs, and to follow the garbage collection process.&lt;/p&gt;
&lt;p&gt;If you want more details, see &lt;a href="/posts/internals-data-representation.html" class="internal"&gt;my post about data representation in CHICKEN&lt;/a&gt;.&lt;/p&gt;&lt;a href="#a-tale-of-two-spaces"&gt;
&lt;h3 id="a-tale-of-two-spaces"&gt;A tale of two spaces&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;CHICKEN divides the heap up in two halves.  While the program is running, only one half is in use.  When this half fills up, we start the garbage collection process.  We trace all the data that's still considered &amp;quot;live&amp;quot; (aka GC &amp;quot;roots&amp;quot;) and copy it over to the other half.&lt;/p&gt;
&lt;p&gt;Let's look at an example:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;  &lt;span class="paren1"&gt;(&lt;span class="default"&gt;cons 5 &amp;#x27;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;  &lt;span class="comment"&gt;; unreferenced, may be collected
&lt;/span&gt;  &lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; x &lt;span class="paren2"&gt;(&lt;span class="default"&gt;cons &lt;span class="paren3"&gt;(&lt;span class="default"&gt;vector 42&lt;/span&gt;)&lt;/span&gt; &amp;#x27;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="comment"&gt;; sticks around&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The half that was full is called the &lt;tt&gt;fromspace&lt;/tt&gt; and the half that starts out empty is called the &lt;tt&gt;tospace&lt;/tt&gt;.  Initially, the &lt;tt&gt;tospace&lt;/tt&gt; is empty, and the data is only in the &lt;tt&gt;fromspace&lt;/tt&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/simple-gc-init.svg" /&gt;&lt;/p&gt;
&lt;p&gt;Then, we move the objects, one at a time, starting at the roots.  So in the example, the pair that we named &amp;quot;x&amp;quot; gets moved first to &lt;tt&gt;tospace&lt;/tt&gt;, while its slots still point into &lt;tt&gt;fromspace&lt;/tt&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/simple-gc-first-move.svg" /&gt;&lt;/p&gt;
&lt;p&gt;The changes are in &lt;i&gt;yellow&lt;/i&gt;.  After tracing the roots, we trace all the contents of the objects in &lt;tt&gt;fromspace&lt;/tt&gt; and copy over the pointed-to objects:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/simple-gc-second-move.svg" /&gt;&lt;/p&gt;
&lt;p&gt;Finally, we're done.  Any remaining objects in &lt;tt&gt;fromspace&lt;/tt&gt; are garbage and can be ignored, effectively &amp;quot;clearing&amp;quot; &lt;tt&gt;fromspace&lt;/tt&gt;, and we flip the two spaces so that &lt;tt&gt;fromspace&lt;/tt&gt; becomes &lt;tt&gt;tospace&lt;/tt&gt; and vice versa:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/simple-gc-done.svg" /&gt;&lt;/p&gt;&lt;a href="#onward-i-mean-forward"&gt;
&lt;h3 id="onward-i-mean-forward"&gt;Onward! I mean, forward!&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;This was a very simple case.  A more complex case is when there are several objects with mutual references.  We must somehow keep track of which objects got moved where, so that we don't copy the same object more than once.&lt;/p&gt;
&lt;p&gt;Another example:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;  &lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; shr &lt;span class="paren2"&gt;(&lt;span class="default"&gt;vector 42&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; x &lt;span class="paren2"&gt;(&lt;span class="default"&gt;cons shr 1&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; y &lt;span class="paren3"&gt;(&lt;span class="default"&gt;cons shr 2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This would look like the following when visualized:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/fwd-gc-init.svg" /&gt;&lt;/p&gt;
&lt;p&gt;As I've explained, roots are copied first, so let's say &lt;tt&gt;shr&lt;/tt&gt; gets copied first:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/fwd-gc-first-move.svg" /&gt;&lt;/p&gt;
&lt;p&gt;As you can see, this introduces something new.  There's a &lt;i&gt;forwarding pointer&lt;/i&gt; stored at the address where we originally found the header of the pair known as &lt;tt&gt;shr&lt;/tt&gt;.  This is done so that we don't have to traverse all the objects pointing to &lt;tt&gt;shr&lt;/tt&gt; (which could even be cyclic!).  Instead, whenever we find an object that holds an address where there now is a forwarding pointer, we derefence the pointer and change the object to point to the target address.&lt;/p&gt;
&lt;p&gt;So, if &lt;tt&gt;x&lt;/tt&gt; is copied next, we get the following picture:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/fwd-gc-second-move.svg" /&gt;&lt;/p&gt;
&lt;p&gt;We actually *always* leave behind a forwarding pointer when an object is copied, because the GC does not &amp;quot;know&amp;quot; whether anything references the object.  I skipped that in the initial examples to keep it simple. And finally, &lt;tt&gt;y&lt;/tt&gt; can be copied:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/fwd-gc-done.svg" /&gt;&lt;/p&gt;
&lt;p&gt;Now you can see, the forwarding pointers are still there in &lt;tt&gt;fromspace&lt;/tt&gt;, but nothing references them anymore.  The GC is now done.  Of course, &lt;tt&gt;fromspace&lt;/tt&gt; and &lt;tt&gt;tospace&lt;/tt&gt; will be flipped (but I'm not showing that here).&lt;/p&gt;&lt;a href="#how-weak-pairs-work-in-the-gc"&gt;
&lt;h2 id="how-weak-pairs-work-in-the-gc"&gt;How weak pairs work in the GC&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Let's make a few changes to our example:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;  &lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; zero &lt;span class="paren2"&gt;(&lt;span class="default"&gt;weak-cons &lt;span class="paren3"&gt;(&lt;span class="default"&gt;vector 0&lt;/span&gt;)&lt;/span&gt; 0&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;  &lt;span class="comment"&gt;;; new - car may be collected
&lt;/span&gt;  &lt;span class="paren1"&gt;(&lt;span class="default"&gt;weak-cons &lt;span class="paren2"&gt;(&lt;span class="default"&gt;vector 9&lt;/span&gt;)&lt;/span&gt; 9&lt;/span&gt;)&lt;/span&gt; &lt;span class="comment"&gt;;; new - may be collected
&lt;/span&gt;  &lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; shr &lt;span class="paren2"&gt;(&lt;span class="default"&gt;vector 42&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; x &lt;span class="paren2"&gt;(&lt;span class="default"&gt;cons shr 1&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; y &lt;span class="paren3"&gt;(&lt;span class="default"&gt;weak-cons shr 2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="comment"&gt;;; changed to be weak
&lt;/span&gt;  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;set! shr #f&lt;/span&gt;)&lt;/span&gt; &lt;span class="comment"&gt;;; new - dropping root for shr
&lt;/span&gt;  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; z &lt;span class="paren3"&gt;(&lt;span class="default"&gt;weak-cons &lt;span class="paren4"&gt;(&lt;span class="default"&gt;vector #f&lt;/span&gt;)&lt;/span&gt; 3&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="comment"&gt;;; new - car may be collected&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Now, &lt;tt&gt;y&lt;/tt&gt; is changed to be a weak pair holding &lt;tt&gt;shr&lt;/tt&gt; in its &lt;tt&gt;car&lt;/tt&gt;, while &lt;tt&gt;x&lt;/tt&gt; is still a normal pair with the same object in its &lt;tt&gt;car&lt;/tt&gt;.  The &lt;tt&gt;shr&lt;/tt&gt; variable is also cleared, so that only &lt;tt&gt;x&lt;/tt&gt; holds onto &lt;tt&gt;shr&lt;/tt&gt;'s old value strongly.  We've added a few more weak pairs while we're at it.&lt;/p&gt;
&lt;p&gt;This &lt;tt&gt;weak-cons&lt;/tt&gt; procedure does not exist in CHICKEN 5.3.0; this is what we'll be adding.  It creates a pair whose &lt;tt&gt;car&lt;/tt&gt; field is a weak reference.  The &lt;tt&gt;cdr&lt;/tt&gt; field is a regular reference.  The reason for having the &lt;tt&gt;cdr&lt;/tt&gt; be a regular reference is that this allows us to build up lists of items which may be collected.  The &amp;quot;spine&amp;quot; of the list will remain intact, but the list entries will be cleared (see below).&lt;/p&gt;
&lt;p&gt;Let's take a look at our new initial situation:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/weak-pair-naive-gc-init.svg" /&gt;&lt;/p&gt;
&lt;p&gt;The GC will start with the live objects, as usual.  Let's start at the top, copying &lt;tt&gt;zero&lt;/tt&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/weak-pair-naive-gc-first-move.svg" /&gt;&lt;/p&gt;
&lt;p&gt;Since &lt;tt&gt;zero&lt;/tt&gt; is a weak pair, we &lt;i&gt;won't&lt;/i&gt; traverse the &lt;tt&gt;car&lt;/tt&gt; slot, keeping the vector it points to in &lt;tt&gt;fromspace&lt;/tt&gt;.  This is intentional, as the GC treats weak pairs differently; only the &lt;tt&gt;cdr&lt;/tt&gt; slot gets scanned, while the &lt;tt&gt;car&lt;/tt&gt; gets skipped and left as a &amp;quot;dangling&amp;quot; pointer into &lt;tt&gt;fromspace&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;We'll fix that later, as we don't want to keep this situation after the garbage collection process is done.&lt;/p&gt;
&lt;p&gt;Normally we'd pick up &lt;tt&gt;shr&lt;/tt&gt; next, but that is not a root anymore. Let's continue with &lt;tt&gt;x&lt;/tt&gt; instead:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/weak-pair-naive-gc-second-move.svg" /&gt;&lt;/p&gt;
&lt;p&gt;Then, as we scan over the contents of &lt;tt&gt;x&lt;/tt&gt;, we encounter what used to be &lt;tt&gt;shr&lt;/tt&gt; and move it, updating the pointer in &lt;tt&gt;x&lt;/tt&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/weak-pair-naive-gc-third-move.svg" /&gt;&lt;/p&gt;
&lt;p&gt;Next, we move &lt;tt&gt;y&lt;/tt&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/weak-pair-naive-gc-fourth-move.svg" /&gt;&lt;/p&gt;
&lt;p&gt;You'll notice that because it's a weak pair, its &lt;tt&gt;car&lt;/tt&gt; slot does not get updated to the new location of what used to be &lt;tt&gt;shr&lt;/tt&gt;, even though that vector has already been copied.  As mentioned before, we'll fix this up later.&lt;/p&gt;
&lt;p&gt;Finally, &lt;tt&gt;z&lt;/tt&gt; gets moved:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/weak-pair-naive-gc-last-move.svg" /&gt;&lt;/p&gt;
&lt;p&gt;I'm sure you've noticed that now we're left with a big spaghetti bowl of pointers, some of which are still pointing into &lt;tt&gt;fromspace&lt;/tt&gt;. So let's investigate how we can fix this mess.&lt;/p&gt;&lt;a href="#fixing-up-the-dangling-weak-pairs-naively"&gt;
&lt;h3 id="fixing-up-the-dangling-weak-pairs-naively"&gt;Fixing up the dangling weak pairs, naively&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;It just so happens that CHICKEN internally already has support for &lt;i&gt;weak pairs&lt;/i&gt;.  Those are pairs whose &lt;tt&gt;car&lt;/tt&gt; field holds objects that may be collected.  These are used solely in the symbol table, so that symbols aren't maintained indefinitely.  This is important because it stops symbol table stuffing attacks.  Those are a form of Denial of Service (DoS) by forcing the system to eat up all memory.&lt;/p&gt;
&lt;p&gt;In this current implementation, the only weak pairs in existence are those in the symbol table's hash bucket chains.  So, the solution there is very simple: traverse all the symbol table buckets and update weak pointers.&lt;/p&gt;
&lt;p&gt;So we traverse the slots like during normal GC's &lt;i&gt;mark&lt;/i&gt; operation, but with two exceptions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When we mark the slot, we don't cause the contents to be copied over into &lt;tt&gt;tospace&lt;/tt&gt;, but &lt;i&gt;only&lt;/i&gt; chase any forwarding pointers.&lt;/li&gt;
&lt;li&gt;When we encounter a pointer into &lt;tt&gt;fromspace&lt;/tt&gt;, we replace the slot with a special &amp;quot;broken weak pair&amp;quot; marker.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;That would yield this final picture:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/weak-pair-naive-gc-fixup.svg" /&gt;&lt;/p&gt;
&lt;p&gt;As you can see, &lt;i&gt;all&lt;/i&gt; the weak pairs have their &lt;tt&gt;car&lt;/tt&gt; slots updated, even the ones that we could consider as garbage, like the two at the top.  Those get the special value &lt;tt&gt;#!bwp&lt;/tt&gt;, or &amp;quot;broken weak pointer&amp;quot; to indicate that the value originally stored there is no longer live.&lt;/p&gt;&lt;a href="#smarter-fixing-up-of-weak-pairs"&gt;
&lt;h2 id="smarter-fixing-up-of-weak-pairs"&gt;Smarter fixing up of weak pairs&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Traversing all the weak pairs is fine when we know every single one in the system.  When only hash table buckets in the symbol table may be weak, that's the case.  But now we want to expose weak pairs to the user, what do we do?&lt;/p&gt;
&lt;p&gt;The simplest solution would be to add a table or list of all the weak pairs &lt;i&gt;as they're constructed&lt;/i&gt;, or &lt;i&gt;as the GC encounters them&lt;/i&gt;. This has a few problems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It is wasteful of memory, as the extra pointers in this table would be redundant.&lt;/li&gt;
&lt;li&gt;If done during garbage collection, we'll have to dynamically allocate &lt;i&gt;during a GC&lt;/i&gt;, when memory is already tight (and it's slow).&lt;/li&gt;
&lt;li&gt;We'd end up traversing potentially loads and loads of dead weak pairs that would be themselves collected, as in the example above.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Alternatively, you could traverse the &lt;i&gt;entire heap&lt;/i&gt; again after GC and mark the weak pairs.  In fact, that's &lt;a href="https://github.com/cisco/ChezScheme/blob/b8c3631731a8bef7cbdf1fa4cf7080cb5252e482/c/gc.c#L1101" class="external"&gt;what Chez Scheme does&lt;/a&gt;.  However, Chez has separate heaps for different types of objects (known as a &lt;a href="https://foldoc.org/Big+bag+of+pages" class="external"&gt;BIBOP&lt;/a&gt; scheme).  This has the advantage of traversing &lt;i&gt;only&lt;/i&gt; the live weak pairs, instead of every single live object.&lt;/p&gt;
&lt;p&gt;In CHICKEN, we'd be traversing every single object, as we store everything on a single heap.  If the heap is large, this would be wasteful.  But at least we wouldn't have to traverse dead weak pairs!&lt;/p&gt;
&lt;p&gt;When looking into this problem, I decided to study the Schemes which have weak pointers.  Those were Chez Scheme, Chibi Scheme and MIT Scheme.  Of those, only MIT Scheme has a Cheney-style copying garbage collector with a single heap like CHICKEN does.  The sources to MIT Scheme are well-documented, so I quickly found &lt;a href="https://git.savannah.gnu.org/cgit/mit-scheme.git/tree/src/microcode/gcloop.c?id=176cd871bdd9c9dabcb8ad602da0b618be2d0373#n789" class="external"&gt;how they do it&lt;/a&gt;, and boy is it &lt;i&gt;clever&lt;/i&gt;!&lt;/p&gt;
&lt;p&gt;MIT Scheme's solution:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Traverses &lt;i&gt;only&lt;/i&gt; the still-live weak pairs,&lt;/li&gt;
&lt;li&gt;introduces only &lt;i&gt;a single word&lt;/i&gt; of memory overhead,&lt;/li&gt;
&lt;li&gt;and is brilliantly simple once you get how it works.&lt;/li&gt;&lt;/ul&gt;&lt;a href="#garbage-collecting-weak-pairs-mit-style"&gt;
&lt;h3 id="garbage-collecting-weak-pairs-mit-style"&gt;Garbage collecting weak pairs, MIT style&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Let's take a closer look at that end state of that last GC run. Remember that a forwarding pointer overwrites the original header of the object that used to live there.  But the memory of the slots is &lt;i&gt;still sitting there&lt;/i&gt;, allocated but unused!&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/weak-pair-naive-gc-with-empty-slots.svg" /&gt;&lt;/p&gt;
&lt;p&gt;The great idea in MIT Scheme is that we can &amp;quot;recycle&amp;quot; that unused memory and store a linked list of still-live weak pairs in that space. The extra word of overhead I mentioned before acts as the head of that list.  Let's look at how that looks during the GC, by replaying that last run, but with MIT Scheme's algorithm for tracking weak pairs:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/weak-pair-improved-gc-init.svg" /&gt;&lt;/p&gt;
&lt;p&gt;The initial state is the same, except we have the additional weak pair chain head.  The GC again starts at the top, copying &lt;tt&gt;zero&lt;/tt&gt;, same as before, but with one addition.  When the forwarding pointer gets created, we notice that it's a weak pair.  This causes the weak pair chain head to get modified so it points to the new forwarding pointer. The original value of the chain head (the empty list marker) gets stored where the old weak pair's &lt;tt&gt;car&lt;/tt&gt; slot used to be.&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/weak-pair-improved-gc-first-move.svg" /&gt;&lt;/p&gt;
&lt;p&gt;Again, we continue with &lt;tt&gt;x&lt;/tt&gt;, which is a regular pair, so nothing interesting happens to the space behind the forwarding pointer:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/weak-pair-improved-gc-second-move.svg" /&gt;&lt;/p&gt;
&lt;p&gt;Then, as we scan over the contents of &lt;tt&gt;x&lt;/tt&gt;, we again encounter what used to be &lt;tt&gt;shr&lt;/tt&gt; and move it, updating the pointer in &lt;tt&gt;x&lt;/tt&gt;.  The forwarding pointer for &lt;tt&gt;shr&lt;/tt&gt; is also not put in the chain because &lt;tt&gt;shr&lt;/tt&gt; is not a weak pair:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/weak-pair-improved-gc-third-move.svg" /&gt;&lt;/p&gt;
&lt;p&gt;Next, we move &lt;tt&gt;y&lt;/tt&gt;.  Because it is a weak pair, we again link up its forwarding pointer into the chain that we're building up.  This means the pointer in the weak chain head (which pointed to &lt;tt&gt;zero&lt;/tt&gt;'s original address) gets put in the old &lt;tt&gt;car&lt;/tt&gt; field of &lt;tt&gt;y&lt;/tt&gt;, and the head itself now points to &lt;tt&gt;y&lt;/tt&gt;'s forwarding pointer:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/weak-pair-improved-gc-fourth-move.svg" /&gt;&lt;/p&gt;
&lt;p&gt;Finally, &lt;tt&gt;z&lt;/tt&gt; gets moved.  Since it is also a weak pair, when making the forwarding pointer we also link it up into the chain:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/weak-pair-improved-gc-last-move.svg" /&gt;&lt;/p&gt;
&lt;p&gt;Finally, we now only need to traverse the weak pairs by following the trail of pointers starting at the head of the live weak pair chain. For each of the forwarding pointers in the chain:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Follow the forwarding pointer to its corresponding live weak pair,&lt;/li&gt;
&lt;li&gt;take that pair's &lt;tt&gt;car&lt;/tt&gt;,&lt;/li&gt;
&lt;li&gt;check if the &lt;tt&gt;car&lt;/tt&gt; refers to a forwarding pointer.  If it does:&lt;/li&gt;
&lt;li&gt;update the &lt;tt&gt;car&lt;/tt&gt; to the forwarding pointer's destination.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;I'm not going to do this one by one as it's pretty obvious.  I will show you the result of this walk:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/weak-pair-improved-gc-fixup.svg" /&gt;&lt;/p&gt;
&lt;p&gt;You can see that we've only updated three out of four weak pairs - exactly the number of weak pairs that got copied during this GC and are still considered live.  Because only weak pairs that exist in &lt;tt&gt;tospace&lt;/tt&gt; &lt;i&gt;have&lt;/i&gt; to be updated, we are doing the absolute minimum work necessary.&lt;/p&gt;
&lt;p&gt;The nice thing about this is, that even if you produce &lt;i&gt;lots&lt;/i&gt; of garbage weak pairs, they don't have any additional impact on GC performance.  Only those weak pairs that survive garbage collection will be scanned and updated.&lt;/p&gt;
&lt;p&gt;When implementing this improvement I noticed that our performance on benchmarks improved a little bit, even though they don't use weak pairs directly.  This was all due to only scanning copied weak pairs and not having to scan the entire symbol table on every GC.&lt;/p&gt;
&lt;p&gt;With the support for user-facing weak pairs in place, supporting line numbers in the interpreter was &lt;a href="https://lists.nongnu.org/archive/html/chicken-hackers/2023-06/msg00020.html" class="external"&gt;relatively easy&lt;/a&gt;.  This means that debugging your code will be easier starting with the upcoming 5.4 release of CHICKEN!&lt;/p&gt;&lt;a href="#further-reading"&gt;
&lt;h2 id="further-reading"&gt;Further reading&lt;/h2&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;At the &lt;a href="https://wiki.call-cc.org/event/village-chickens-2023" class="external"&gt;Village CHICKENs event&lt;/a&gt;, I presented my findings about how to add weak references. &lt;a href="https://code.more-magic.net/weak-refs-for-chicken/tree/weak-refs.org" class="external"&gt;Slides are here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Back in 2014, &lt;a href="https://www.sitepoint.com/symbol-gc-ruby-2-2/" class="external"&gt;Ruby added symbol GC&lt;/a&gt; to stop symbol table stuffing attacks.  It also improved performance because the GC had to do less work copying stale symbols.  The flurry of interest in symbol table stuffing attacks in Ruby was also my inspiration for &lt;a href="https://lists.gnu.org/archive/html/chicken-hackers/2016-08/msg00018.html" class="external"&gt;fixing&lt;/a&gt; and &lt;a href="https://lists.gnu.org/archive/html/chicken-hackers/2016-09/msg00002.html" class="external"&gt;improving&lt;/a&gt; the symbol GC in CHICKEN.&lt;/li&gt;
&lt;li&gt;The manual to MIT Scheme has a &lt;a href="https://web.mit.edu/scheme_v9.2/doc/mit-scheme-ref/Weak-Pairs.html" class="external"&gt;section on weak pairs&lt;/a&gt;, and the manual to Chez Scheme &lt;a href="https://cisco.github.io/ChezScheme/csug9.5/smgmt.html#./smgmt:h2" class="external"&gt;has its own&lt;/a&gt;, slightly different API.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://apps.dtic.mil/sti/pdfs/ADA190383.pdf" class="external"&gt;MultiScheme: A Parallel Processing System Based on MIT Scheme&lt;/a&gt; by James S. Miller. This is the paper that introduces the &lt;tt&gt;weak-cons&lt;/tt&gt; operation and explains in more detail how the MIT Scheme GC was modified, in the same way we modified CHICKEN's GC.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://legacy.cs.indiana.edu/~dyb/pubs/bibop.pdf" class="external"&gt;Don't stop the BIBOP: Flexible and Efficient Storage Management for Dynamically Typed Languages&lt;/a&gt; by R. Kent Dybvig, David Eby, and Carl Bruggeman. This paper explains how Chez Scheme's allocation scheme works. We've toyed with the idea of implementing a BIBOP allocator and GC in CHICKEN as well, but it'd be a large undertaking without knowing for sure that it would improve performance.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dspace.mit.edu/bitstream/handle/1721.1/6278/AIM-420.pdf" class="external"&gt;Data representations in PDP-10 MacLISP&lt;/a&gt; by Guy L. Steele describes the original BIBOP allocation scheme.&lt;/li&gt;&lt;/ul&gt;</content>
    <id>tag:more-magic,2023-06-27:/posts/weak-references.html</id>
    <published>2023-06-27T11:48:10Z</published>
    <title type="text">Adding weak references to CHICKEN</title>
    <updated>2023-06-27T11:48:10Z</updated>
    <link href="https://www.more-magic.net/posts/weak-references.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;Recently I joined &lt;a href="https://www.bevuta.com" class="external"&gt;bevuta IT&lt;/a&gt;, where I am now working on a big project written in &lt;a href="https://www.clojure.org/" class="external"&gt;Clojure&lt;/a&gt;.  I'm very fortunate to be working in a Lisp for my day job!&lt;/p&gt;
&lt;p&gt;As I've mostly worked with Scheme and have used other Lisps here and there, I would like to share my perspective on the language.&lt;/p&gt;&lt;a href="#overall-design"&gt;
&lt;h2 id="overall-design"&gt;Overall design&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;From a first view, it is pretty clear that Clojure has been designed from scratch by (mostly) one person who is experienced with Lisps and as a language designer.  It is quite clean and has &lt;a href="https://download.clojure.org/papers/clojure-hopl-iv-final.pdf" class="external"&gt;a clear vision&lt;/a&gt;. Most of the standard library has a very consistent API.  It's also nice that it's a &lt;a href="http://www.nhplace.com/kent/Papers/Technical-Issues.html" class="external"&gt;Lisp-1&lt;/a&gt;, which obviously appeals to me as a Schemer.&lt;/p&gt;
&lt;p&gt;My favourite aspect of the language is that everything is designed with a functional-first mindset.  This means I can program in the same functional style as I tend to do in Scheme.  Actually, it's even more functional, because for example its maps (what would be hash tables in Scheme) are much less clunky to deal with.  In Scheme, SRFI-69 hash tables are quite imperative, with &lt;tt&gt;hash-table-set!&lt;/tt&gt; and &lt;tt&gt;hash-table-update!&lt;/tt&gt; being the ways to insert new entries, which of course mutate the existing object.  Similarly, Clojure vectors can easily be extended (on either end!) functionally.&lt;/p&gt;
&lt;p&gt;The underlying design of Clojure's data structures must be different. It needs to efficiently support functional updates; you don't want to fully copy a hash table or vector whenever you add a new entry. I am not sure how efficient everything is, because the system I'm working on isn't in production yet.  A quick look &lt;a href="https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentArrayMap.java" class="external"&gt;at the code&lt;/a&gt; implies that various data structures are used under the hood for what looks like one data structure in the language.  That's a lot of complexity!  I'm not sure that's a tradeoff I'd be happy to make.  It makes it harder to reason about performance.  You might just be using a completely different underlying data structure than expected, depending on which operations you've performed.&lt;/p&gt;&lt;a href="#non-lispiness"&gt;
&lt;h2 id="non-lispiness"&gt;(non) Lispiness&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;To a seasoned Lisp or Scheme programmer, Clojure can appear positively &lt;i&gt;bizarre&lt;/i&gt;.  For example, while there is a &lt;tt&gt;cons&lt;/tt&gt; function, there are no cons cells, and &lt;tt&gt;car&lt;/tt&gt; and &lt;tt&gt;cdr&lt;/tt&gt; don't exist.  Instead, it has &lt;tt&gt;first&lt;/tt&gt; and &lt;tt&gt;rest&lt;/tt&gt;, which are definitely saner names for a language designed from scratch.  It has &amp;quot;persistent lists&amp;quot;, which are immutable lists, but in most day to day programming you will not even be &lt;b&gt;using&lt;/b&gt; lists, as weird as that sounds!&lt;/p&gt;&lt;a href="#symbols-and-keywords"&gt;
&lt;h3 id="symbols-and-keywords"&gt;Symbols and keywords&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;One thing that really surprised me is that symbols are not interned. This means that two symbols which are constructed on the fly, or when read from the same REPL, are not identical (as in &lt;tt&gt;eq&lt;/tt&gt; or &lt;tt&gt;eq?&lt;/tt&gt;) to one another:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight lisp-language"&gt;user&amp;gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;= &amp;#x27;foo &amp;#x27;foo&lt;/span&gt;)&lt;/span&gt;
true
user&amp;gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;identical? &amp;#x27;foo &amp;#x27;foo&lt;/span&gt;)&lt;/span&gt;
false&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Keywords seem to fulfil most &amp;quot;symbolic programming&amp;quot; use cases.  For example, they're almost always used as &amp;quot;keys&amp;quot; in maps or when specifying options for functions.  Keywords &lt;i&gt;are&lt;/i&gt; interned:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight lisp-language"&gt;user&amp;gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;= &lt;span class="keyword"&gt;:foo&lt;/span&gt; &lt;span class="keyword"&gt;:foo&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
true
user&amp;gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;identical? &lt;span class="keyword"&gt;:foo&lt;/span&gt; &lt;span class="keyword"&gt;:foo&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
true&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Code is still (mostly) expressed as lists of symbols, though.  When you're writing macros you'll deal with them a lot.  But in &amp;quot;regular&amp;quot; code you will deal more with keywords, maps and vectors than lists and symbols.&lt;/p&gt;&lt;a href="#numeric-tower"&gt;
&lt;h3 id="numeric-tower"&gt;Numeric tower&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;A favorite gotcha of mine is that integers &lt;a href="https://clojure.org/reference/data_structures#Numbers" class="external"&gt;are not automatically promoted to bignums&lt;/a&gt; like in most Lisps that support bignums.  If you need bignums, you have to use special-purpose operators like &lt;tt&gt;+'&lt;/tt&gt; and &lt;tt&gt;-'&lt;/tt&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight lisp-language"&gt;user&amp;gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;* &lt;span class="paren2"&gt;(&lt;span class="default"&gt;bit-shift-left 1 62&lt;/span&gt;)&lt;/span&gt; 2&lt;/span&gt;)&lt;/span&gt;
Execution error &lt;span class="paren1"&gt;(&lt;span class="default"&gt;ArithmeticException&lt;/span&gt;)&lt;/span&gt; at user/eval51159 &lt;span class="paren1"&gt;(&lt;span class="default"&gt;REPL:263&lt;/span&gt;)&lt;/span&gt;.
integer overflow
user&amp;gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;*&amp;#x27; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;bit-shift-left 1 62&lt;/span&gt;)&lt;/span&gt; 2&lt;/span&gt;)&lt;/span&gt;
9223372036854775808N

user&amp;gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;* &lt;span class="paren2"&gt;(&lt;span class="default"&gt;bit-shift-left 1 62&lt;/span&gt;)&lt;/span&gt; 2N&lt;/span&gt;)&lt;/span&gt; &lt;span class="comment"&gt;; regular * supports BigInt inputs, though
&lt;/span&gt;9223372036854775808N
user&amp;gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;* 1N 1&lt;/span&gt;)&lt;/span&gt; &lt;span class="comment"&gt;; but small BigInts aren&amp;#x27;t normalized to Java Longs
&lt;/span&gt;1N&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This could lead to better performance at the cost of more headaches when dealing with the accidental large numbers in code that was not prepared for them.&lt;/p&gt;
&lt;p&gt;What about rationals, you ask?  Well, those are just treated as &amp;quot;the unusual, slow case&amp;quot;.  So even though they &lt;i&gt;do&lt;/i&gt; normalize to regular integers when simplifying, operations on those always return BigInts:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight lisp-language"&gt;user&amp;gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;+ 1/2 1/4&lt;/span&gt;)&lt;/span&gt;
3/4
user&amp;gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;+ 1/2 1/2&lt;/span&gt;)&lt;/span&gt;
1N
user&amp;gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;/ 1 2&lt;/span&gt;)&lt;/span&gt; &lt;span class="comment"&gt;; division is the odd one out
&lt;/span&gt;1/2
user&amp;gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;/ 4 2&lt;/span&gt;)&lt;/span&gt; &lt;span class="comment"&gt;; it doesn&amp;#x27;t just punt and always produce bignums, either:
&lt;/span&gt;2&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The sad part is, bitwise operators do not support bignums, &lt;i&gt;at all&lt;/i&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight lisp-language"&gt;user&amp;gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;bit-shift-right 9223372036854775808N 62&lt;/span&gt;)&lt;/span&gt;
Execution error &lt;span class="paren1"&gt;(&lt;span class="default"&gt;IllegalArgumentException&lt;/span&gt;)&lt;/span&gt; at user/eval51167 &lt;span class="paren1"&gt;(&lt;span class="default"&gt;REPL:273&lt;/span&gt;)&lt;/span&gt;.
bit operation not supported for: class clojure.lang.BigInt
user&amp;gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;bit-shift-right&amp;#x27; 9223372036854775808N 62&lt;/span&gt;)&lt;/span&gt; &lt;span class="comment"&gt;; does not exist
&lt;/span&gt;Syntax error compiling at &lt;span class="paren1"&gt;(&lt;span class="default"&gt;*cider-repl test:localhost:46543&lt;span class="paren2"&gt;(&lt;span class="default"&gt;clj&lt;/span&gt;)&lt;/span&gt;*:276:7&lt;/span&gt;)&lt;/span&gt;.
Unable to resolve symbol: bit-shift-right&amp;#x27; in this context&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;There's one benefit to all of this: if you know the types of something going into numeric operators, you will typically know the type that comes out, because there is no automatic coercion.  Like I mentioned, this may provide a performance benefit, but it also simplifies reasoning about types.  Unfortunately, this does not work as well as you would hope because division may change the type, depending on whether the result divides cleanly or not.&lt;/p&gt;&lt;a href="#syntax"&gt;
&lt;h3 id="syntax"&gt;Syntax&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;For many Lispers, this is the elephant in the room.  Clojure certainly qualifies as a Lisp, but it is much heavier on syntax than most other Lisps.  Let's look at a small contrived example:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight lisp-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; [foo-value &lt;span class="paren2"&gt;(&lt;span class="default"&gt;+ 1 2&lt;/span&gt;)&lt;/span&gt;
      bar-value &lt;span class="paren2"&gt;(&lt;span class="default"&gt;* 3 4&lt;/span&gt;)&lt;/span&gt;]
  {&lt;span class="keyword"&gt;:foo&lt;/span&gt; foo-value
   &lt;span class="keyword"&gt;:bar&lt;/span&gt; bar-value}&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This is a &lt;tt&gt;let&lt;/tt&gt; just like in Common Lisp or Scheme.  The bindings are put inside square brackets, which is literal syntax for &lt;i&gt;vectors&lt;/i&gt;.  Inside this vector, key-value pairs are interleaved, like in a Common Lisp &lt;a href="http://www.lispworks.com/documentation/lw50/CLHS/Body/26_glo_p.htm#property_list" class="external"&gt;property list&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The lack of extra sets of &amp;quot;grouping&amp;quot; parentheses is a bit jarring at first, but you get used to it rather quickly.  I still mess up occasionally when I accidentally get an odd number of entries in a binding vector.  Now, the&lt;tt&gt; {:foo foo-value :bar bar-value} &lt;/tt&gt;syntax is a &lt;i&gt;map&lt;/i&gt;, which acts like a hash table (more on that below).&lt;/p&gt;
&lt;p&gt;There doesn't seem to be a good rationale about why vectors are used instead of regular lists, though.  What I &lt;i&gt;do&lt;/i&gt; really like is that all the binding forms (even function signatures!) support &lt;a href="https://clojure.org/guides/destructuring" class="external"&gt;destructuring&lt;/a&gt;.  The syntax for destructuring maps is a bit ugly, but having it available is super convenient.&lt;/p&gt;
&lt;p&gt;What I regard as a design mistake is the fact that Clojure allows for optional commas in lists and function calls.  Commas are just whitespace to the reader.  For example:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight lisp-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;= [1, 2, 3, 4] [1 2 3 4]&lt;/span&gt;)&lt;/span&gt; =&amp;gt; true
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;= &amp;#x27;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;1, 2, 3, 4&lt;/span&gt;)&lt;/span&gt; &amp;#x27;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;1 2 3 4&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; =&amp;gt; true
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;= {&lt;span class="keyword"&gt;:foo&lt;/span&gt; 1, &lt;span class="keyword"&gt;:bar&lt;/span&gt; 2, &lt;span class="keyword"&gt;:qux&lt;/span&gt; 3} {&lt;span class="keyword"&gt;:foo&lt;/span&gt; 1 &lt;span class="keyword"&gt;:bar&lt;/span&gt; 2 &lt;span class="keyword"&gt;:qux&lt;/span&gt; 3}&lt;/span&gt;)&lt;/span&gt; =&amp;gt; true
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;= &lt;span class="paren2"&gt;(&lt;span class="default"&gt;foo 1, 2, 3, 4&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;foo 1 2 3 4&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; =&amp;gt; true
&lt;span class="comment"&gt;;; A bit silly:
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;= [,,,,,,1,,,2,3,4,,,,,,] [1 2 3 4]&lt;/span&gt;)&lt;/span&gt; =&amp;gt; true&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Maybe this is to make up for removing the extra grouping parentheses in &lt;tt&gt;let&lt;/tt&gt;, &lt;tt&gt;cond&lt;/tt&gt; and map literal syntax?  With commas you can add back some clarity about which items belong together.  Rarely anybody uses commas in real code, though.  And since it's optional it doesn't make much sense.&lt;/p&gt;
&lt;p&gt;This has an annoying ripple effect on quasiquotation.  Due to this decision, a different character has to be used for &lt;tt&gt;unquote&lt;/tt&gt;, because the comma was already taken:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight lisp-language"&gt;`&lt;span class="paren1"&gt;(&lt;span class="default"&gt;1 2 ~&lt;span class="paren2"&gt;(&lt;span class="default"&gt;+ 1 2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; =&amp;gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;1 2 3&lt;/span&gt;)&lt;/span&gt;
`&lt;span class="paren1"&gt;(&lt;span class="default"&gt;1 2 ~@&lt;span class="paren2"&gt;(&lt;span class="default"&gt;list 3 4&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; =&amp;gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;1 2 3 4&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This might seem like a small issue, but it is an unnecessary and stupid distraction.&lt;/p&gt;&lt;a href="#minimalism"&gt;
&lt;h2 id="minimalism"&gt;Minimalism&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;One of the main reasons I enjoy Scheme so much is its goal of minimalism.  This is achieved through elegant building blocks.  This is embodied by the &lt;a href="https://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-3.html#%_chap_Temp_3" class="external"&gt;Prime Clingerism&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;  Programming languages should be designed not by piling feature on
  top of feature, but by removing the weaknesses and restrictions
  that make additional features appear necessary.&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Let's check the size of the &lt;tt&gt;clojure.core&lt;/tt&gt; library.  It clocks in at 640 identifiers (v1.10.1), which is a lot more than R5RS Scheme's 218 identifiers.  It's not an entirely fair comparison as Scheme without SRFI-1 or SRFI-43 or an FFI has much less functionality as well. Therefore, I think Clojure's core library is fairly small but not exactly an exercise in minimalism.&lt;/p&gt;
&lt;p&gt;Clojure reduces its API size considerably by having a &amp;quot;&lt;a href="https://clojure.org/reference/sequences" class="external"&gt;sequence&lt;/a&gt; abstraction&amp;quot;. This is similar to Common Lisp's sequences: you can call &lt;tt&gt;map&lt;/tt&gt;, &lt;tt&gt;filter&lt;/tt&gt; or &lt;tt&gt;length&lt;/tt&gt; on any sequence-type object: lists, vectors, strings and even maps (which are treated as key/value pairs). However, it is less hacky than in Common Lisp because for example with &lt;tt&gt;map&lt;/tt&gt; you don't need to specify which kind of sequence you want to get back.  I get the impression that in Common Lisp this abstraction is not very prominent or used often but in Clojure &lt;i&gt;everything&lt;/i&gt; uses sequences.  What I also liked is that sequences can be &lt;i&gt;lazy&lt;/i&gt;, which removes the need for special operators as well.&lt;/p&gt;
&lt;p&gt;If you compare this to Scheme, you have special-purpose procedures for every concrete type: &lt;tt&gt;length&lt;/tt&gt;, &lt;tt&gt;vector-length&lt;/tt&gt;, &lt;tt&gt;string-length&lt;/tt&gt; etc.  And there's no &lt;tt&gt;vector-map&lt;/tt&gt; in the standard, so you need &lt;a href="https://srfi.schemers.org/srfi-43/srfi-43.html#vector-map" class="external"&gt;&lt;tt&gt;vector-map&lt;/tt&gt; from SRFI 43&lt;/a&gt;.  Lazy lists are a &lt;a href="https://srfi.schemers.org/srfi-41/srfi-41.html" class="external"&gt;separate type&lt;/a&gt; with its own set of specialized operators.  And so on and so forth.  Using concrete types everywhere provides for less abstract and confusing code and the performance characteristics of an algorithm tend to be clearer, but it also leads to a massive growth in library size.&lt;/p&gt;
&lt;p&gt;After a while I really started noticing mistakes that make additional features appear necessary: for example, there's a special macro called &lt;tt&gt;loop&lt;/tt&gt; to make tail recursive calls.  This uses a keyword &lt;tt&gt;recur&lt;/tt&gt; to call back into the loop.  In Scheme, you would do that with a named &lt;tt&gt;let&lt;/tt&gt; where you can choose your own identifier to recur.  It's also not possible to nest such Clojure loops, because the identifier is hardcoded.  So, this called for adding &lt;a href="https://archive.clojure.org/design-wiki/display/design/Named%2Bloops%2Bwith%2Brecur-to.html" class="external"&gt;another feature&lt;/a&gt;, which is currently in proposal.  Speaking of &lt;tt&gt;recur&lt;/tt&gt;, it is also used for tail recursive self-calls.  It relies on the programmer rather than the compiler to mark calls as tail recursive. I find this a bit of a cop-out, especially in a language that is so heavily functional.  Especially since this doesn't work for mutually tail-recursive functions.  The &lt;a href="https://www.windley.com/archives/2008/11/tail_optimized_mutual_recursion_in_clojure.shtml" class="external"&gt;official way to do those&lt;/a&gt; is even more of a crutch.&lt;/p&gt;
&lt;p&gt;I find the special syntax for one-off lambdas &lt;tt&gt;#(foo %)&lt;/tt&gt; just as misguided as &lt;a href="https://srfi.schemers.org/srfi-26/srfi-26.html" class="external"&gt;SRFI 26&lt;/a&gt; (&lt;tt&gt;cut&lt;/tt&gt; and &lt;tt&gt;cute&lt;/tt&gt;).  You often end up needing to tweak the code in such a way that you have to transform the lambda to a proper &lt;tt&gt;fn&lt;/tt&gt;. And just like &lt;tt&gt;cut&lt;/tt&gt;, it doesn't save that many characters anyway and makes the code less readable.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/-%3E" class="external"&gt;&lt;tt&gt;-&amp;gt;&lt;/tt&gt;&lt;/a&gt; macro is a clever hack which allows you to &amp;quot;thread&amp;quot; values through expressions.  It implicitly adds the value as the first argument to the first forms, the result of that form as the first argument for the next, etc.  Because the core library is quite well-designed, this works 90% of the time.  Then the other 10% you need &lt;a href="https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/-%3E%3E" class="external"&gt;&lt;tt&gt;-&amp;gt;&amp;gt;&lt;/tt&gt;&lt;/a&gt; which does the same but adds the implicit argument at the &lt;i&gt;end&lt;/i&gt; of the forms.  And that's not always enough either, so they decided to add a generic version called &lt;a href="https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/as-%3E" class="external"&gt;&lt;tt&gt;as-&amp;gt;&lt;/tt&gt;&lt;/a&gt; which binds the value to a name so you can put it at any place in the forms.  These macros also don't compose well.  For example, sometimes you need a &lt;tt&gt;let&lt;/tt&gt; in a &lt;tt&gt;-&amp;gt;&lt;/tt&gt; chain to have a temporary binding. That doesn't work because you can't randomly insert forms into &lt;tt&gt;let&lt;/tt&gt;, so you have to split things up again.&lt;/p&gt;
&lt;p&gt;And as I note below, the minimalism is kind of &amp;quot;fake&amp;quot; because some essentials simply aren't provided; you have to rely on Java for that.&lt;/p&gt;&lt;a href="#java-integration"&gt;
&lt;h2 id="java-integration"&gt;Java integration&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Clojure was originally designed as a &amp;quot;hosted language&amp;quot;, so it leverages the JVM.  It does this admirably well; Java classes can be &lt;a href="http://clojure-doc.org/articles/language/interop.html" class="external"&gt;seamlessly invoked through Clojure&lt;/a&gt;, without any ceremony:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight lisp-language"&gt;user&amp;gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;java.util.UUID/randomUUID&lt;/span&gt;)&lt;/span&gt;
#uuid &lt;span class="string"&gt;&amp;quot;bb788bae-5099-4a64-9c37-f6219d40a47f&amp;quot;&lt;/span&gt;

&lt;span class="comment"&gt;;; alternatively:
&lt;/span&gt;user&amp;gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;import &amp;#x27;java.util.UUID&lt;/span&gt;)&lt;/span&gt;
java.util.UUID
user&amp;gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;UUID/randomUUID&lt;/span&gt;)&lt;/span&gt;
#uuid &lt;span class="string"&gt;&amp;quot;0bfd2092-14e1-4b88-a465-18698943ea4e&amp;quot;&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The downside is that the above is &lt;i&gt;the&lt;/i&gt; way to generate a random UUID.  So even though uuids have literal syntax in Clojure (as &lt;tt&gt;#uuid &amp;quot;...&amp;quot;&lt;/tt&gt;), there is no Lispy API for them in the Clojure standard library.  This can be pretty frustrating, especially in the beginning. There's no clear indication where to look; sometimes you'll be poring over Java language docs for random stuff you thought would have a Clojure interface (like, say, creating temporary files or dealing with byte arrays).  At those moments, you're basically programming Java with parentheses.&lt;/p&gt;
&lt;p&gt;Having said that, there will often be community-provided nicer APIs for many of those things, but then you need to decide between adding an extra dependency just for a slightly nicer syntax.&lt;/p&gt;&lt;a href="#development-style"&gt;
&lt;h2 id="development-style"&gt;Development style&lt;/h2&gt;&lt;/a&gt;&lt;a href="#repl-driven-development"&gt;
&lt;h3 id="repl-driven-development"&gt;REPL-driven development&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Speaking of Java, one thing that constantly bothers me is the slow startup times of the REPL.  In my current project, it takes almost 30 seconds to boot up a development REPL.  Half a minute!&lt;/p&gt;
&lt;p&gt;Luckily, there's great Slime-like Emacs integration with &lt;a href="https://cider.mx/" class="external"&gt;CIDER&lt;/a&gt;.  Basically, the only sane way to do iterative development is by connecting to a REPL first thing you do and then sending your code to it all the time.&lt;/p&gt;
&lt;p&gt;Now, this may sound weird from a Scheme programmer, but I never fully bought into the REPL style of developing.  Sure, I experiment all the time in the REPL to try out a new API design or to quickly iterate on some function I'm writing.  But my general development style tends more towards the &amp;quot;save and then run the test suite from an xterm&amp;quot;. Relying solely on the REPL just &amp;quot;feels&amp;quot; jarring to me.  I also constantly run into issues where re-evaluating a buffer doesn't get rid of global state that was built up on a previous run.  When this happens, I'm testing an old version of some function without realising it.  Keeping track of the &amp;quot;live&amp;quot; state versus the textual code I'm looking at is a total mind fuck for me.  I don't understand how others can do this.&lt;/p&gt;
&lt;p&gt;Another thing I seem to constantly do is write some code, have the tests go all green, only to see the CI crash on some cyclic dependency in my namespaces.  The REPL does not always see those, because reloading a buffer with a namespace declaration works just fine when you loaded the imported namespaces before, even though they refer to the namespace being re-evaluated.&lt;/p&gt;
&lt;p&gt;One thing I really find very nice when you're using CIDER is that everything (and I do mean &lt;i&gt;everything&lt;/i&gt;) from Clojure is just a &amp;quot;jump to source&amp;quot; away.  Most of the builtin functions seems to be written in Clojure itself.  For example, if you want to know how &lt;tt&gt;map&lt;/tt&gt; is implemented, you can just press &lt;tt&gt;M-.&lt;/tt&gt; to see it.&lt;/p&gt;&lt;a href="#maps-and-keywords-for-everything"&gt;
&lt;h3 id="maps-and-keywords-for-everything"&gt;Maps and keywords for everything&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;One thing you'll really notice is that in idiomatic Clojure code, maps are used for everything.  A map is a functionally updateable hash table.  It looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight lisp-language"&gt;{&lt;span class="keyword"&gt;:key-1&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;value 1&amp;quot;&lt;/span&gt;
 &lt;span class="keyword"&gt;:key-2&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;value 2&amp;quot;&lt;/span&gt;}&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This lends to a very dynamic style of programming, very much like you would in (dare I say it?) PHP.  A bit of a strange comparison, but PHP also makes dealing with arrays (which double as maps in a weird way) extremely ergonomic.  There, missing nested keys are automatically created on the fly and because of a strange quirk in its developmental history, arrays are the only objects which are passed by value.  This means you can program in a referentially transparent way, while still mutating them inside functions at will.  Not exactly the same mechanism, but the end effect on programming style feels very similar: you reach for them whenever you want to bunch some stuff together.  It is the go-to data structure when you need flexibility.&lt;/p&gt;
&lt;p&gt;In other Lisps you'd use alists (or plists, or SRFI-69 hash tables) for this, but they don't deal so well with nested maps and the library is not as convenient.  For example, you can easily select, drop and rename keys in a map:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight lisp-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;-&amp;gt; {&lt;span class="keyword"&gt;:key-1&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;value 1&amp;quot;&lt;/span&gt; &lt;span class="keyword"&gt;:key-2&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;value 2&amp;quot;&lt;/span&gt;}
    &lt;span class="paren2"&gt;(&lt;span class="default"&gt;set/rename-keys {&lt;span class="keyword"&gt;:key-1&lt;/span&gt; &lt;span class="keyword"&gt;:key}&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren2"&gt;(&lt;span class="default"&gt;dissoc &lt;span class="keyword"&gt;:key-2&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren2"&gt;(&lt;span class="default"&gt;assoc &lt;span class="keyword"&gt;:foo&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; =&amp;gt; {&lt;span class="keyword"&gt;:key&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;value 1&amp;quot;&lt;/span&gt; &lt;span class="keyword"&gt;:foo&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;}&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This &lt;tt&gt;-&amp;gt;&lt;/tt&gt; notation took me a while to get used to by the way, and I'm still not entirely comfortable with it.  I explained how it works above.  It's a macro for &amp;quot;threading&amp;quot; expressions.  In Scheme, you'd probably use a &lt;tt&gt;let*&lt;/tt&gt; for this, or something.  In Clojure that would look like this:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight lisp-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; [map {&lt;span class="keyword"&gt;:key-1&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;value 1&amp;quot;&lt;/span&gt; &lt;span class="keyword"&gt;:key-2&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;value 2&amp;quot;&lt;/span&gt;}
      map &lt;span class="paren2"&gt;(&lt;span class="default"&gt;set/rename-keys map {&lt;span class="keyword"&gt;:key-1&lt;/span&gt; &lt;span class="keyword"&gt;:key}&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
      map &lt;span class="paren2"&gt;(&lt;span class="default"&gt;dissoc map &lt;span class="keyword"&gt;:key-2&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
      map &lt;span class="paren2"&gt;(&lt;span class="default"&gt;assoc map &lt;span class="keyword"&gt;:foo&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;]
  map&lt;/span&gt;)&lt;/span&gt; =&amp;gt; {&lt;span class="keyword"&gt;:key&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;value 1&amp;quot;&lt;/span&gt; &lt;span class="keyword"&gt;:foo&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;}&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, the version with &lt;tt&gt;-&amp;gt;&lt;/tt&gt; is much more convenient and less repetitive.  Unfortunately, it doesn't compose that well (duh, it's a macro), but because of the way the standard library is designed it is more useful than it would seem at first glance.&lt;/p&gt;
&lt;p&gt;Anyway, the way maps are typically used everywhere in a project means that there's a lot less &amp;quot;structure&amp;quot; to your data structures.  It is extremely convenient to use maps, even though there are also things like &lt;a href="https://clojure.org/reference/datatypes" class="external"&gt;records&lt;/a&gt; and &lt;a href="https://clojure.org/reference/protocols" class="external"&gt;protocols&lt;/a&gt;.  Because of their convenience, you'll end up using maps for everything.  As I've noticed in my refactorings, when you change the structure of maps, a lot of code is going to break without a clear indication of where it went wrong.&lt;/p&gt;
&lt;p&gt;This is made extra painful by &amp;quot;nil punning&amp;quot;.  For example, when you look up something in a map that doesn't exist, &lt;tt&gt;nil&lt;/tt&gt; is returned. In Clojure, many operations (like &lt;tt&gt;first&lt;/tt&gt; or &lt;tt&gt;rest&lt;/tt&gt;) on &lt;tt&gt;nil&lt;/tt&gt; just return &lt;tt&gt;nil&lt;/tt&gt; instead of raising an error.  So, when you think you are looking up something in a map, but the &amp;quot;map&amp;quot; is actually &lt;tt&gt;nil&lt;/tt&gt;, it will not give an error, but it will return &lt;tt&gt;nil&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Now like I said, &lt;i&gt;sometimes&lt;/i&gt; you may get an error on &lt;tt&gt;nil&lt;/tt&gt;.  It's a bit unclear which operations are nil-punning and which will give a proper error.  So when you finally get a &lt;tt&gt;nil&lt;/tt&gt; error, you will have a hell of a time trying to trace back where this &lt;tt&gt;nil&lt;/tt&gt; got generated, as that may have been several function calls ago.  This is an example where I really like the strictness of Scheme as compared to some other Lisps, as nil-punning is traditionally a dynamic Lisp thing; it's not unique to Clojure.&lt;/p&gt;&lt;a href="#multimethods-with-keywords"&gt;
&lt;h3 id="multimethods-with-keywords"&gt;Multimethods with keywords&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Initially, I was quite impressed by the way multimethods work; they're super simple and clean, yet powerful.  First, you declare the multimethod and a &amp;quot;decision procedure&amp;quot;, which returns a value that can be compared:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight lisp-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;defmulti&lt;/span&gt;&lt;/i&gt; say-hi &lt;span class="keyword"&gt;:kind&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;defmethod&lt;/span&gt;&lt;/i&gt; say-hi &lt;span class="keyword"&gt;:default&lt;/span&gt; [animal]
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;println &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="keyword"&gt;:name&lt;/span&gt; animal&lt;/span&gt;)&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;says hello&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;defmethod&lt;/span&gt;&lt;/i&gt; say-hi &lt;span class="keyword"&gt;:duck&lt;/span&gt; [animal]
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;println &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="keyword"&gt;:name&lt;/span&gt; animal&lt;/span&gt;)&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;says quack&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;defmethod&lt;/span&gt;&lt;/i&gt; say-hi &lt;span class="keyword"&gt;:dog&lt;/span&gt; [animal]
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;println &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="keyword"&gt;:name&lt;/span&gt; animal&lt;/span&gt;)&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;says woof&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;say-hi {&lt;span class="keyword"&gt;:name&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Daffy&amp;quot;&lt;/span&gt; &lt;span class="keyword"&gt;:kind&lt;/span&gt; &lt;span class="keyword"&gt;:duck}&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;  =&amp;gt; &lt;span class="string"&gt;&amp;quot;Daffy says quack&amp;quot;&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;say-hi {&lt;span class="keyword"&gt;:name&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Pluto&amp;quot;&lt;/span&gt; &lt;span class="keyword"&gt;:kind&lt;/span&gt; &lt;span class="keyword"&gt;:dog}&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;   =&amp;gt; &lt;span class="string"&gt;&amp;quot;Pluto says woof&amp;quot;&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;say-hi {&lt;span class="keyword"&gt;:name&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Peter&amp;quot;&lt;/span&gt; &lt;span class="keyword"&gt;:kind&lt;/span&gt; &lt;span class="keyword"&gt;:human}&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; =&amp;gt; &lt;span class="string"&gt;&amp;quot;Peter says hello&amp;quot;&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Using multimethods takes some care and taste, because it splits up your logic.  So instead of having one place where you have decisions made with an &lt;tt&gt;if&lt;/tt&gt; or &lt;tt&gt;cond&lt;/tt&gt; tree, you have a function call and then depending on how the multimethod was defined, a different function will be called.  This is basically what makes C++ so difficult to deal with in large projects: when people use function overloading, it can get really messy.  You need to figure out which of the many things called &amp;quot;say-hi&amp;quot; is actually called in a situation, before you can dive into that implementation.&lt;/p&gt;
&lt;p&gt;Compared to the insane amount of customizability that e.g. CLOS offers you, the design restraint shown in Clojure multimethods was nice to see, but then I realised this simplicity can be completely defeated by building &lt;a href="https://clojure.org/reference/multimethods" class="external"&gt;hierarchies&lt;/a&gt;. That is, Clojure allows you to define a hierarchy on &lt;i&gt;keywords&lt;/i&gt;. This was a huge wtf for me, because to me, keywords are just static entities that are unrelated to eachother.&lt;/p&gt;
&lt;p&gt;When you realise how Clojure keywords can be namespaced, it makes slightly more sense: this gives them some separation.&lt;/p&gt;
&lt;p&gt;A keyword can appear in &amp;quot;bare&amp;quot; form like &lt;tt&gt;:foo&lt;/tt&gt;.  This is a globally scoped keyword that belongs to no particular code.  It's definitely not smart to hang a hierarchy onto such a keyword, and you're also better off not adding any &amp;quot;meta attributes&amp;quot; to them.&lt;/p&gt;
&lt;p&gt;The other form is &lt;tt&gt;::foo&lt;/tt&gt;, which puts the keyword in the current namespace, which is shorthand for &lt;tt&gt;::more-magic.net/foo&lt;/tt&gt; if you are in the &lt;tt&gt;more-magic.net&lt;/tt&gt; namespace.&lt;/p&gt;&lt;a href="#conclusion"&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;All in all, Clojure is a well-designed language with neat features and it's certainly a lot better than most other JVM languages.  There are things in it that I wish Scheme had, and it's certainly functional and modern.  As a general programming language, I just can't get over the JVM and all its Java trappings, which is just not my cup of tea.&lt;/p&gt;
&lt;p&gt;Apart from the JVM, there are some gratuitous departures from traditional Lisps, especially the &amp;quot;rich syntax&amp;quot; and the extreme reliance and overloading of keywords and maps.&lt;/p&gt;
&lt;p&gt;As always, such things are a matter of taste, so take my opinion with a large grain of salt.&lt;/p&gt;</content>
    <id>tag:more-magic,2021-03-03:/posts/thoughts-on-clojure.html</id>
    <published>2021-03-03T15:31:50Z</published>
    <title type="text">Clojure from a Schemer's perspective</title>
    <updated>2021-03-03T15:31:50Z</updated>
    <link href="https://www.more-magic.net/posts/thoughts-on-clojure.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;As you may know, I co-maintain the &lt;a href="https://wiki.call-cc.org/egg/uri-generic" class="external"&gt;uri-generic egg&lt;/a&gt;, together with Ivan Raikov.  We had just been working on &lt;a href="https://bugs.call-cc.org/ticket/1530" class="external"&gt;fixing a bug&lt;/a&gt; and porting it to CHICKEN 5 when I stumbled across the &lt;a href="https://url.spec.whatwg.org/" class="external"&gt;WHATWG URL specification&lt;/a&gt;, an evolution over &lt;a href="https://tools.ietf.org/html/rfc3986" class="external"&gt;RFC 3986&lt;/a&gt;.  I found it hard to believe they dropped the formal grammar from the RFC, so I checked the issue queue and found &lt;a href="https://github.com/whatwg/url/issues/24" class="external"&gt;a closed ticket from 2015&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;They replaced the BNF with a series of steps which is several pages long and overly concerned with implementation-specific details.&lt;/p&gt;
&lt;p&gt;It really got to me that such an important and basic part of the web stack is so informally specified.  So I wrote an appeal to them to restore a formal grammar in this ticket.  I think the reasons are worth being spread more widely, so I'm reproducing it here on my blog.&lt;/p&gt;&lt;a href="#my-request"&gt;
&lt;h2 id="my-request"&gt;My request&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;I would like to offer my opinion from an implementor's perspective and hopefully convince the WG to restore a formal grammar. Let me start by providing some background on where I'm coming from. Feel free to skip this next section.&lt;/p&gt;&lt;a href="#my-background"&gt;
&lt;h3 id="my-background"&gt;My background&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;I am the co-maintainer of the &lt;a href="https://wiki.call-cc.org/egg/uri-generic" class="external"&gt;uri-generic egg&lt;/a&gt; for &lt;a href="https://call-cc.org" class="external"&gt;CHICKEN Scheme&lt;/a&gt;. This implementation attempts to follow RFC 3986 to the letter, and this has resulted in what IMO is a very high-quality implementation (at least, as far as parsing is concerned; URL construction still has some known issues). Oftentimes when we ran into issues, we've compared it with other implementations. It turns out that many of these are lacking in some way or another.  I think the main reason is that they're not attempting to really implement the formal grammar (even if they claim to be RFC compliant), while we do. We even have a &lt;a href="http://bugs.call-cc.org/browser/project/release/5/uri-generic/trunk/alternatives" class="external"&gt;growing repository&lt;/a&gt; of alternative implementations using different parser generators which all pass &lt;a href="http://bugs.call-cc.org/browser/project/release/5/uri-generic/trunk/tests" class="external"&gt;the same test suite&lt;/a&gt;!  (feel free to now call me a smug Lisp/Scheme weenie :) )&lt;/p&gt;
&lt;p&gt;I wasn't aware of the WHATWG spec until I saw it mentioned in a &lt;a href="https://daniel.haxx.se/blog/2018/09/09/libcurl-gets-a-url-api/" class="external"&gt;libcurl post&lt;/a&gt;.  It piqued my interest because I'm always looking for more test cases. The &lt;a href="https://github.com/web-platform-tests/wpt/blob/master/url/resources/urltestdata.json" class="external"&gt;web platform test suite&lt;/a&gt; looks like a big, juicy set to start using in our egg's tests.  I'd also consider implementing the WHATWG spec if this increases compatibility with other implementations.&lt;/p&gt;&lt;a href="#what-i-expect-from-a-spec"&gt;
&lt;h3 id="what-i-expect-from-a-spec"&gt;What I expect from a spec&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;As an implementor, I routinely check the RFC's ABNF as a guide to determine what a valid URL should look like. If someone finds a certain URL our implementation doesn't parse, or if it parses an URL that it shouldn't, the first thing I do is go back to the ABNF in the RFC to verify the behaviour. It is compact, to the point and, for a trained eye, it is trivial to quickly determine if a parser should accept a given (sub)string or not.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://tools.ietf.org/html/rfc3986#appendix-A" class="external"&gt;collected ABNF of RFC 3986&lt;/a&gt; is a brief three screenful. In contrast, the &lt;a href="https://url.spec.whatwg.org/#concept-basic-url-parser" class="external"&gt;algorithm&lt;/a&gt; in the WHATWG spec is roughly eighteen screenful.  It is an overly detailed and nonstandard way of defining a grammar.  This makes it harder to determine which language is accepted by this algorithm. It also makes it hard for me to determine what the changes are, compared to the RFC.  Implementing the WHATWG spec would (for me) involve a complete rewrite.&lt;/p&gt;
&lt;p&gt;The specification is so focused on the mechanics of a specific manual parsing technique that it almost precludes parser generators or other implementations.  Parser generators have a long tradition in theory and practice, and can generate &lt;b&gt;efficient&lt;/b&gt; language recognisers. Even today, it is an active research field; PEG grammars for example have been &amp;quot;discovered&amp;quot; as recently as 2004.&lt;/p&gt;
&lt;p&gt;The way I think about it is that the purpose of this spec is to define what a URL &amp;quot;officially&amp;quot; looks like. So, as an implementor, I don't understand the hesitation to supply a formal grammar. Not having one will likely result in different people interpreting the spec differently.  This results in _less_ interoperability, which defeats the point of a spec.&lt;/p&gt;&lt;a href="#other-reasons-why-i-think-a-formal-grammar-is-important"&gt;
&lt;h3 id="other-reasons-why-i-think-a-formal-grammar-is-important"&gt;Other reasons why I think a formal grammar is important&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Finally, I would like to emphasise &lt;a href="http://langsec.org/" class="external"&gt;the importance of parsers based on formal grammars over ad hoc ones for security reasons&lt;/a&gt;. Let's say you have a pipeline of multiple processors which use different URL parsers. For example, you might have a HTML parser on a comment form which cleans URLs by dropping JavaScript and data URLs, among other things, or a mail client which blocks intranet or file system-local URLs before invoking an HTML viewer.  If these are all ad hoc &amp;quot;informal&amp;quot; parsers that try to &amp;quot;fix&amp;quot; syntactically invalid URLs, it is nigh-impossible to verify that filtering them for &amp;quot;safe&amp;quot; URLs is correct.  That's because it's impossible to decide which language is really accepted by an ad hoc implementation.  An implementation further down the stack might interpret an URL (radically) different from one up the stack and you have a nice little exploit in the making.&lt;/p&gt;
&lt;p&gt;If you're not convinced by my measly attempts at explaining this idea, please watch the talk &lt;a href="https://media.ccc.de/v/28c3-4763-en-the_science_of_insecurity" class="external"&gt;&amp;quot;The Science of Insecurity&amp;quot;&lt;/a&gt;. Meredith Patterson states the case much more eloquently than I ever could. This talk was an absolute eye-opener for me.&lt;/p&gt;
&lt;p&gt;With this context, it baffled me to read the statement that &amp;quot;there are several large parts of the spec that cannot be captured by any kind of grammar&amp;quot;. This is literally equivalent to saying &amp;quot;we can't know if an URL will be valid without evaluating the algorithm&amp;quot;.  This means you cheerfully drag the halting problem into what should be a simple, straightforward notation (come on, URLs aren't &lt;i&gt;that&lt;/i&gt; ill-defined!). As far as I can tell, the RFC defines a regular grammar. The decision to go from a regular to an unrestricted grammar should not be taken lightly!&lt;/p&gt;</content>
    <id>tag:more-magic,2018-09-11:/posts/an-appeal-to-whatwg-uri-spec.html</id>
    <published>2018-09-11T20:09:20Z</published>
    <title type="text">An appeal to the WHATWG</title>
    <updated>2018-09-11T20:09:20Z</updated>
    <link href="https://www.more-magic.net/posts/an-appeal-to-whatwg-uri-spec.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;We're getting close to a CHICKEN 5 release, so let's take a look at the cool new stuff!&lt;/p&gt;&lt;a href="#overhaul-of-built-in-modules"&gt;
&lt;h2 id="overhaul-of-built-in-modules"&gt;Overhaul of built-in modules&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;The biggest change you'll notice when you fire up CHICKEN and start to use it is that the modules that come shipped with core are completely different from CHICKEN 4.  The functionality is mostly the same, but we moved things around (a lot!) to make things more logical.&lt;/p&gt;
&lt;p&gt;This is also the main reason we decided to bump the major version number: the modules have different names, procedures have been renamed, merged or dropped.&lt;/p&gt;
&lt;p&gt;You can take a look at &lt;a href="https://wiki.call-cc.org/man/5/Included%20modules" class="external"&gt;the complete list&lt;/a&gt; in the CHICKEN 5 manual.  We've taken the module layout from &lt;a href="http://www.r7rs.org" class="external"&gt;R7RS small&lt;/a&gt; as inspiration, but since CHICKEN is still an R5RS Scheme first (with r7rs being &lt;a href="https://wiki.call-cc.org/egg/r7rs" class="external"&gt;an optional extension&lt;/a&gt;) we had to make some changes.&lt;/p&gt;
&lt;p&gt;So, we define a &lt;a href="https://wiki.call-cc.org/man/5/Module%20scheme" class="external"&gt;&lt;tt&gt;scheme&lt;/tt&gt; module&lt;/a&gt; which contains the entire R5RS language.  For everything that is a CHICKEN-specific extension to standard R5RS Scheme, we put it under a &lt;tt&gt;(chicken ...)&lt;/tt&gt; name, which tries to follow the R7RS naming conventions.&lt;/p&gt;
&lt;p&gt;For example, R7RS defines a &lt;tt&gt;(scheme process-context)&lt;/tt&gt; module with the following procedures:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;tt&gt;command-line&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;exit&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;emergency-exit&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;get-environment-variable&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;get-environment-variables&lt;/tt&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Likewise, CHICKEN defines a &lt;tt&gt;(chicken process-context)&lt;/tt&gt; module, which is a superset of the corresponding R7RS module.  Take a look at &lt;a href="https://wiki.call-cc.org/man/5/Module%20(chicken%20process-context)" class="external"&gt;its manual page&lt;/a&gt;; you can see that it defines many more procedures, but it includes all the standard ones too.&lt;/p&gt;
&lt;p&gt;By using the R7RS names but with &lt;tt&gt;scheme&lt;/tt&gt; replaced by &lt;tt&gt;chicken&lt;/tt&gt;, the new modules should be easy to remember for anyone used to R7RS. Of course, you can still write portable standard R7RS programs via the &lt;a href="https://wiki.call-cc.org/egg/r7rs" class="external"&gt;r7rs egg&lt;/a&gt;, which defines a 100% compatible &lt;tt&gt;(scheme process-context)&lt;/tt&gt; module with &lt;i&gt;only&lt;/i&gt; the R7RS identifiers.&lt;/p&gt;
&lt;p&gt;There is one important caveat: Because our &lt;tt&gt;scheme&lt;/tt&gt; modules exports everything from &lt;i&gt;R5RS&lt;/i&gt; Scheme, we don't provide, say, a &lt;tt&gt;(chicken cxr)&lt;/tt&gt; module for all the &lt;tt&gt;cadadr&lt;/tt&gt;, &lt;tt&gt;caddar&lt;/tt&gt; and so on, because those are all in &lt;tt&gt;scheme&lt;/tt&gt;.  This also means that &lt;a href="https://wiki.call-cc.org/man/5/Module%20(chicken%20load)" class="external"&gt;the &lt;tt&gt;(chicken load)&lt;/tt&gt; module&lt;/a&gt; does &lt;i&gt;not&lt;/i&gt; export &lt;tt&gt;load&lt;/tt&gt;; that's already in &lt;tt&gt;scheme&lt;/tt&gt;.  Instead, it defines various non-standard CHICKEN extensions like &lt;tt&gt;load-relative&lt;/tt&gt; and such.&lt;/p&gt;&lt;a href="#saner-module-imports"&gt;
&lt;h2 id="saner-module-imports"&gt;Saner module imports&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Speaking of modules, we've improved the way modules are linked into user code.  In CHICKEN 4, there's a very strict distinction between modules and (compilation) units.  This was an endless source of confusion for beginners.  For example, why did &lt;tt&gt;(import foo)&lt;/tt&gt; give an error when you tried to actually refer to an identifier from the &lt;tt&gt;foo&lt;/tt&gt; module?  That's because &lt;tt&gt;import&lt;/tt&gt; didn't actually load the code, just the import library.  To actually load the code &lt;i&gt;and&lt;/i&gt; import the library, you needed &lt;tt&gt;(use foo)&lt;/tt&gt;.  You could also load the code &lt;i&gt;without&lt;/i&gt; importing it via &lt;tt&gt;(require-library foo)&lt;/tt&gt;.  This should help with cross-compilation.  The idea was that you would only need to load the import library on the host, and have the library itself compiled for the target, but in practice you needed to compile the library twice anyway (once on the host, once for the target).&lt;/p&gt;
&lt;p&gt;We got rid of this mess: now the canonical way to import the &lt;tt&gt;foo&lt;/tt&gt; library is simply &lt;tt&gt;(import foo)&lt;/tt&gt;.  For more info, see &lt;a href="https://lists.gnu.org/archive/html/chicken-hackers/2014-07/msg00007.html" class="external"&gt;this post by Felix&lt;/a&gt; outlining how to improve imports.&lt;/p&gt;&lt;a href="#full-numeric-tower"&gt;
&lt;h2 id="full-numeric-tower"&gt;Full numeric tower&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Of course, support for the full numeric tower is a personal favorite of mine, &lt;a href="/posts/numeric-tower-part-1.html" class="internal"&gt;having spent a lot of time&lt;/a&gt; to perfect this stuff!&lt;/p&gt;
&lt;p&gt;Most importantly, this means you no longer need to worry about integer computations over- or underflowing into a flonum and all the weird floating-point problems that entails.  Bignums are also a necessity when dealing with 64-bit numeric C types in the FFI.  For example, we finally support the &lt;tt&gt;size_t&lt;/tt&gt; type correctly.  To me, complex numbers and exact fractions (aka rational numbers) are a nice added bonus, as you could already get them before with the numbers egg. However, by having these types built-in, they're more efficient and you don't have to worry about passing these numbers to code that can't handle them because support happened not to be compiled in.&lt;/p&gt;
&lt;p&gt;Take some time to read &lt;a href="/posts/numeric-tower-part-1.html" class="internal"&gt;my blog series&lt;/a&gt; about the numeric tower if you're interested in the details.&lt;/p&gt;&lt;a href="#declarative-egg-description-language"&gt;
&lt;h2 id="declarative-egg-description-language"&gt;Declarative egg description language&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;The &lt;tt&gt;chicken-install&lt;/tt&gt; program to install eggs was rewritten along with all the surrounding tools.  The main reason to do this was to make the life of package maintainers easier.&lt;/p&gt;
&lt;p&gt;The old version of &lt;tt&gt;chicken-install&lt;/tt&gt; would download, build, install and (optionally) run the unit tests as part of one command.  If any dependencies were missing, it would also recursively download, build, install and run tests for those as well.  The new version cleanly separates these steps, by generating shell scripts (batch files on Windows) that can do the necessary actions to build and install.&lt;/p&gt;
&lt;p&gt;To make this easier, we also had to re-think the egg &amp;quot;language&amp;quot;.  In CHICKEN 4, a &lt;tt&gt;.setup&lt;/tt&gt;-file was simply a Scheme program in which a few helper procedures were available for calling the compiler.  This means it's impossible to create a simple shell script that will separate the build and install steps.  That's why we now have a separate, declarative file which describes the components of an egg. See the &lt;a href="http://wiki.call-cc.org/man/5/Extensions#a-simple-library" class="external"&gt;&lt;tt&gt;.egg&lt;/tt&gt; file documentation&lt;/a&gt; for a concrete example.&lt;/p&gt;
&lt;p&gt;The rewritten &lt;tt&gt;chicken-install&lt;/tt&gt; will now also cache eggs to avoid re-downloading the same eggs again and again.  By default the cache is stored in a dot-directory under the user's home directory.  This can be overridden with the &lt;tt&gt;CHICKEN_EGG_CACHE&lt;/tt&gt; environment variable, which might also help package maintainers take the distributed files from another location.&lt;/p&gt;
&lt;p&gt;See &lt;a href="http://wiki.call-cc.org/chicken-5-roadmap-egg-system" class="external"&gt;these design notes&lt;/a&gt; for more information about the goals and motivations behind the rewrite.&lt;/p&gt;&lt;a href="#improved-support-for-static-compilation"&gt;
&lt;h2 id="improved-support-for-static-compilation"&gt;Improved support for static compilation&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;In principle, CHICKEN 4 has good support for static compilation.  In practice, egg authors would not include the necessary commands for building their libraries statically.  Most people don't have a real need for static linking, which means they tend not to make an effort to support it just in case someone else might need it.&lt;/p&gt;
&lt;p&gt;The upshot of this was that you could only really compile programs statically when they didn't use any eggs, or if you created a custom build script that would compile the eggs manually with the required &lt;tt&gt;-static&lt;/tt&gt; option.  With the new &lt;tt&gt;chicken-install&lt;/tt&gt;, you get static compilation support automatically, for free.&lt;/p&gt;
&lt;p&gt;Note that in CHICKEN 4, you could also build eggs and programs using the so-called &lt;a href="https://wiki.call-cc.org/man/4/Deployment" class="external"&gt;deployment mode&lt;/a&gt;.  This allowed shipping a program with all its libraries in one directory.  This worked quite well if your target platform supported it, but not all platforms did.  Static compilation covers all the use cases that deployment supported and works reliably on all platforms, so we decided to drop deployment mode with all the complexity it brings.&lt;/p&gt;&lt;a href="#other-noteworthy-things"&gt;
&lt;h2 id="other-noteworthy-things"&gt;Other noteworthy things&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;But wait, there's more!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Code generation is now fully deterministic, making builds &lt;a href="https://reproducible-builds.org/" class="external"&gt;reproducible&lt;/a&gt;.  This allows you to verify that any given file of generated C code corresponds to the Scheme source code by recompiling it with the same CHICKEN version, both for user code and for CHICKEN core itself. As an added bonus, because the generated C output is deterministic, &lt;a href="https://ccache.samba.org/" class="external"&gt;ccache&lt;/a&gt; can be used to get much faster builds (before, it would invalidate the cache as each file would be different).&lt;/li&gt;
&lt;li&gt;We've improved how symbols are garbage collected, which was optional and somewhat broken in CHICKEN 4.  This will speed up code that generates many symbols, and stops symbol table stuffing attacks from being a threat.&lt;/li&gt;
&lt;li&gt;We have removed quite a bit of bloat: The srfi-1, srfi-13, srfi-14, srfi-69 and srfi-18 libraries have been removed from core!  Not to worry though; they are now available as eggs.  This will both allow faster development and encourage innovation and competition from alternatives to these non-essential libraries (especially R7RS-large seems to be geared towards renewal of some of these).  We've also moved several non-SRFI procedures from core: object-evict, compile-file, binary-search, procedures for dealing with queues, scan-input-lines and POSIX group-information have all been moved to eggs.  Support for &lt;a href="http://www.swig.org" class="external"&gt;SWIG&lt;/a&gt; has been removed, as it was bit-rotting and nobody seemed to be using it anyway.&lt;/li&gt;
&lt;li&gt;Ports can now be bi-directional, so there's no more unnecessary distinction between input-ports and output ports.  This maps more cleanly to file descriptor semantics, which can also be opened for both reading &lt;i&gt;and&lt;/i&gt; writing.&lt;/li&gt;
&lt;li&gt;Random number generation has been completely replaced.  Before, we used libc's &lt;tt&gt;rand()&lt;/tt&gt;, which produces very low quality random numbers. CHICKEN 5 uses the &lt;a href="http://www.iro.umontreal.ca/%7Epanneton/WELLRNG.html" class="external"&gt;WELL512 PRNG&lt;/a&gt; to generate random integers, and it provides access to the system entropy pool for generating cryptographically secure streams of random bytes (using &lt;tt&gt;/dev/urandom&lt;/tt&gt; on *nix, and &lt;a href="https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/" class="external"&gt;RtlGenRandom&lt;/a&gt; on Windows).&lt;/li&gt;&lt;/ul&gt;&lt;a href="#conclusion"&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;There's a lot to like about the new CHICKEN, so go ahead and give it a spin!  Release candidate 1 &lt;a href="https://lists.gnu.org/archive/html/chicken-announce/2018-08/msg00000.html" class="external"&gt;was made available today&lt;/a&gt; for you to try. The full list of changes can of course be found in the &lt;a href="https://code.call-cc.org/dev-snapshots/2018/08/11/NEWS" class="external"&gt;NEWS file&lt;/a&gt;. If you're already a happy CHICKEN 4 user, we've created a &lt;a href="http://wiki.call-cc.org/porting-c4-to-c5" class="external"&gt;porting guide&lt;/a&gt; for you, to make it easier to make the transition from 4 to 5. If you need more help, you can of course &lt;a href="http://wiki.call-cc.org/discussion-groups" class="external"&gt;contact&lt;/a&gt; the always friendly CHICKEN community.&lt;/p&gt;</content>
    <id>tag:more-magic,2018-08-11:/posts/chicken-5.html</id>
    <published>2018-08-11T09:44:27Z</published>
    <title type="text">What to expect from CHICKEN 5</title>
    <updated>2018-08-11T09:44:27Z</updated>
    <link href="https://www.more-magic.net/posts/chicken-5.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;Now that we have covered the most important algorithms, it's time to take a look at the internal data representation of extended numerals. This will be the final part in this series of posts.&lt;/p&gt;&lt;a href="#ratnums-and-cplxnums"&gt;
&lt;h2 id="ratnums-and-cplxnums"&gt;Ratnums and cplxnums&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Recall from my &lt;a href="/posts/internals-data-representation.html" class="internal"&gt;data representations article&lt;/a&gt; that fixnums are represented as immediate values, directly within a machine word.  Flonums are represented in boxed form, by putting them in an opaque bytevector-like structure.&lt;/p&gt;
&lt;p&gt;The data representations of complex numbers and rational numbers are pretty simple.  Each have their own type tag, and they both contain two slots: the numerator and denominator in case of rational numbers, and the real and imaginary parts in case of complex numbers.&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/numerics-representation.svg" /&gt;&lt;/p&gt;
&lt;p&gt;As you can see in the above diagram, the representations of ratnums and cplxnums are very similar.  In the example, the slots contain just fixnums.  Rational numbers are the simplest here: they can &lt;i&gt;only&lt;/i&gt; contain integers (bignums or fixnums).  Complex numbers can consist of any number type except other complex numbers, but the exactness of the real and imaginary components must match.  This means you can't have &lt;tt&gt;1.5+2/3i&lt;/tt&gt;, for example.&lt;/p&gt;
&lt;p&gt;In its most complex (haha!)  form, a complex number contains a rational number in both the real and the imaginary parts, and these rational numbers both contain bignums as their numerator &lt;i&gt;and&lt;/i&gt; denominator.  In this situation, the entire complex number takes up a whopping minimum of 29 machine words: 3 words for the wrapper complex number, 2 times 3 words for each of the ratnums, and 4 times 5 words for the bignums inside the ratnums.&lt;/p&gt;
&lt;p&gt;We'll now look into why bignums require at least 5 words.&lt;/p&gt;&lt;a href="#bignums"&gt;
&lt;h2 id="bignums"&gt;Bignums&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Initially I tried to represent bignums as a kind of opaque bytevector, much like how flonums are stored.  Memory-wise this is the best representation as it has no unnecessary overhead: only 2 extra words; one for the header and one for the sign.  On a 32-bit machine it would look like this:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/bignums-optimal-representation.svg" /&gt;&lt;/p&gt;
&lt;p&gt;This representation is somewhat wasteful, because it uses a full machine word to represent the sign, which is only one bit of information!  This is done to keep the bignum digits word-aligned, which is important for performance.  The sign could be shoved into the header if we &lt;i&gt;really&lt;/i&gt; wanted to be frugal on memory, but doing so would also complicate type detection.  Alternatively, we could store the bignum's digits in 2s complement form so the sign is simply the high bit of the top digit, but that complicates several algorithms.&lt;/p&gt;
&lt;p&gt;Regarding the &amp;quot;bytevector&amp;quot; part: because the limbs are word-aligned, it makes more sense to represent the size in words rather than bytes. Unfortunately, there's no way to do this with the current data representation of CHICKEN.  This was the direct cause of the following bug: Someone tried to represent the largest known prime number in CHICKEN, and it &lt;a href="http://lists.gnu.org/archive/html/chicken-users/2016-01/msg00089.html" class="external"&gt;failed to behave correctly&lt;/a&gt; because we didn't have enough header bits to represent its size.  This was just for fun, so no harm was done, but when someone will actually need such numbers in practice, they're out of luck.  One of these days we're going to have to tackle this problem...&lt;/p&gt;&lt;a href="#performance-takes-a-hit"&gt;
&lt;h3 id="performance-takes-a-hit"&gt;Performance takes a hit&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;When I first &lt;a href="http://lists.gnu.org/archive/html/chicken-hackers/2015-02/msg00008.html" class="external"&gt;integrated the &amp;quot;numbers&amp;quot; egg into CHICKEN 5&lt;/a&gt;, I also did some benchmarking.  It turned out that my initial version made some benchmarks up to 8 times slower, though on average it would slow things down by a factor of 2.  As pointed out by &lt;a href="http://lists.gnu.org/archive/html/chicken-hackers/2015-02/msg00018.html" class="external"&gt;Alex Shinn&lt;/a&gt; and &lt;a href="http://lists.gnu.org/archive/html/chicken-hackers/2015-02/msg00019.html" class="external"&gt;Felix Winkelmann&lt;/a&gt;, the reason it impacts some benchmarks so badly has to do with allocation.&lt;/p&gt;
&lt;p&gt;Let's compile a loop going from zero to &lt;tt&gt;n&lt;/tt&gt;, like so:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="comment"&gt;;; Very silly code, calculates 100 * 100 in a stupid way
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; lp &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;i 0&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;if&lt;/span&gt;&lt;/i&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;= i 100&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren3"&gt;(&lt;span class="default"&gt;* i i&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren3"&gt;(&lt;span class="default"&gt;lp &lt;span class="paren4"&gt;(&lt;span class="default"&gt;add1 i&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Originally, in CHICKEN 4 without the full numeric tower, the compiled C code looked like this:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="comment"&gt;/* lp in k207 in k204 in k201 */&lt;/span&gt;
&lt;span class="symbol"&gt;static&lt;/span&gt; &lt;span class="symbol"&gt;void&lt;/span&gt; C_fcall f_220&lt;span class="paren1"&gt;(&lt;span class="default"&gt;C_word t0,C_word t1,C_word t2&lt;/span&gt;)&lt;/span&gt;&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  C_word tmp;
  C_word t3;
  C_word t4;
  C_word t5;
  C_word t6;
  C_word *a;
loop:
  C_check_for_interrupt;
  &lt;span class="symbol"&gt;if&lt;/span&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;!C_demand&lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_calculate_demand&lt;span class="paren4"&gt;(&lt;span class="default"&gt;4, 0, 2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    C_save_and_reclaim_args&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="symbol"&gt;void&lt;/span&gt; *&lt;/span&gt;)&lt;/span&gt;trf_220, 3, t0, t1, t2&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt;
  a=C_alloc&lt;span class="paren2"&gt;(&lt;span class="default"&gt;4&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* Allocate flonum for overflow situation */&lt;/span&gt;
  &lt;span class="symbol"&gt;if&lt;/span&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_truep&lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_i_nequalp&lt;span class="paren4"&gt;(&lt;span class="default"&gt;t2, C_fix&lt;span class="paren5"&gt;(&lt;span class="default"&gt;100&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    t3=t1;
    &lt;span class="paren3"&gt;{&lt;span class="default"&gt;
      C_word av2&lt;span class="paren4"&gt;[&lt;span class="default"&gt;2&lt;/span&gt;]&lt;/span&gt;;
      av2&lt;span class="paren4"&gt;[&lt;span class="default"&gt;0&lt;/span&gt;]&lt;/span&gt; = t3;
      av2&lt;span class="paren4"&gt;[&lt;span class="default"&gt;1&lt;/span&gt;]&lt;/span&gt; = C_a_i_times&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&amp;amp;a, 2, t2, t2&lt;/span&gt;)&lt;/span&gt;;
      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;C_proc&lt;/span&gt;)&lt;/span&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;span class="symbol"&gt;void&lt;/span&gt;*&lt;/span&gt;)&lt;/span&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;*&lt;span class="paren6"&gt;(&lt;span class="default"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;C_word*&lt;/span&gt;)&lt;/span&gt;t3+1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;2, av2&lt;/span&gt;)&lt;/span&gt;;
    &lt;/span&gt;}&lt;/span&gt;
  &lt;/span&gt;}&lt;/span&gt; &lt;span class="symbol"&gt;else&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    t3 = C_a_i_plus&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&amp;amp;a, 2, t2, C_fix&lt;span class="paren4"&gt;(&lt;span class="default"&gt;1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
    C_trace&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;test.scm:4: lp&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
    t5=t1;
    t6=t3;
    t1=t5;
    t2=t6;
    &lt;span class="symbol"&gt;goto&lt;/span&gt; loop;
  &lt;/span&gt;}&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;It's not much to look at, but this is very close to optimal code: It's a C loop, which allocates a fixed size of memory from the stack/nursery into which it can write the result of &lt;tt&gt;+&lt;/tt&gt; or &lt;tt&gt;*&lt;/tt&gt;, in case they would overflow.&lt;/p&gt;
&lt;p&gt;The compiler knows how it can compile &lt;tt&gt;+&lt;/tt&gt; and &lt;tt&gt;*&lt;/tt&gt; to &amp;quot;inlineable&amp;quot; C functions.  Many of the most performance-critical functions are built into the compiler like that.  But because the compiler (currently) doesn't perform range analysis, it's not smart enough to figure out that none of these operators in this example can cause an overflow.  This bites us especially hard when introducing bignums: because we need to assume that &lt;i&gt;any&lt;/i&gt; operator may overflow, we &lt;i&gt;must&lt;/i&gt; be able to allocate a bignum.  And assuming the result of these operators may be bignums, the next iteration of the loop is a bignum.  Adding two bignums of unknown sizes together results in another bignum of unknown size.&lt;/p&gt;
&lt;p&gt;Because of the above, we can't pre-allocate in a tight C loop. Instead, we must split our loop in two.  This is needed to allow the garbage collector to kick in: if you'll recall from the &lt;a href="/posts/internals-gc.html" class="internal"&gt;garbage collector post&lt;/a&gt;, we need a continuation both for liveness analysis and as a place to jump back to after GC.&lt;/p&gt;
&lt;p&gt;One part of our &lt;tt&gt;lp&lt;/tt&gt; calls an allocating procedure, wrapping up the other part in a continuation:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="comment"&gt;/* k251 in lp in k223 in k220 in k217 in k214 (first part of our &amp;quot;lp&amp;quot;) */&lt;/span&gt;
&lt;span class="symbol"&gt;static&lt;/span&gt; &lt;span class="symbol"&gt;void&lt;/span&gt; C_ccall f_253&lt;span class="paren1"&gt;(&lt;span class="default"&gt;C_word c, C_word *av&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  C_word tmp;
  C_word t0 = av&lt;span class="paren2"&gt;[&lt;span class="default"&gt;0&lt;/span&gt;]&lt;/span&gt;;
  C_word t1 = av&lt;span class="paren2"&gt;[&lt;span class="default"&gt;1&lt;/span&gt;]&lt;/span&gt;;
  C_word t2;
  C_word *a;
  C_check_for_interrupt;
  &lt;span class="symbol"&gt;if&lt;/span&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;!C_demand&lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_calculate_demand&lt;span class="paren4"&gt;(&lt;span class="default"&gt;0, c, 2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    C_save_and_reclaim&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="symbol"&gt;void&lt;/span&gt; *&lt;/span&gt;)&lt;/span&gt;f_253, 2, av&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt;
  C_trace&lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;test.scm:6: lp&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
  t2 = &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_word*&lt;/span&gt;)&lt;/span&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;C_word*&lt;/span&gt;)&lt;/span&gt;t0&lt;/span&gt;)&lt;/span&gt;&lt;span class="paren3"&gt;[&lt;span class="default"&gt;2&lt;/span&gt;]&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;span class="paren2"&gt;[&lt;span class="default"&gt;1&lt;/span&gt;]&lt;/span&gt;;
  f_236&lt;span class="paren2"&gt;(&lt;span class="default"&gt;t2, &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;C_word*&lt;/span&gt;)&lt;/span&gt;t0&lt;/span&gt;)&lt;/span&gt;&lt;span class="paren3"&gt;[&lt;span class="default"&gt;3&lt;/span&gt;]&lt;/span&gt;, t1&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;

&lt;span class="comment"&gt;/* lp in k223 in k220 in k217 in k214 (second part of our &amp;quot;lp&amp;quot;) */&lt;/span&gt;
&lt;span class="symbol"&gt;static&lt;/span&gt; &lt;span class="symbol"&gt;void&lt;/span&gt; C_fcall f_236&lt;span class="paren1"&gt;(&lt;span class="default"&gt;C_word t0, C_word t1, C_word t2&lt;/span&gt;)&lt;/span&gt;&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  C_word tmp;
  C_word t3;
  C_word *a;
  C_check_for_interrupt;
  &lt;span class="symbol"&gt;if&lt;/span&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;!C_demand&lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_calculate_demand&lt;span class="paren4"&gt;(&lt;span class="default"&gt;4, 0, 3&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    C_save_and_reclaim_args&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="symbol"&gt;void&lt;/span&gt; *&lt;/span&gt;)&lt;/span&gt;trf_236, 3, t0, t1, t2&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt;
  a=C_alloc&lt;span class="paren2"&gt;(&lt;span class="default"&gt;4&lt;/span&gt;)&lt;/span&gt;;
  &lt;span class="symbol"&gt;if&lt;/span&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_truep&lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_i_nequalp&lt;span class="paren4"&gt;(&lt;span class="default"&gt;t2, C_fix&lt;span class="paren5"&gt;(&lt;span class="default"&gt;100&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    C_trace&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;test.scm:5: *&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
    &lt;span class="paren3"&gt;{&lt;span class="default"&gt;
      C_word av2&lt;span class="paren4"&gt;[&lt;span class="default"&gt;4&lt;/span&gt;]&lt;/span&gt;;
      av2&lt;span class="paren4"&gt;[&lt;span class="default"&gt;0&lt;/span&gt;]&lt;/span&gt; = C_SCHEME_UNDEFINED;
      av2&lt;span class="paren4"&gt;[&lt;span class="default"&gt;1&lt;/span&gt;]&lt;/span&gt; = t1;
      av2&lt;span class="paren4"&gt;[&lt;span class="default"&gt;2&lt;/span&gt;]&lt;/span&gt; = t2;
      av2&lt;span class="paren4"&gt;[&lt;span class="default"&gt;3&lt;/span&gt;]&lt;/span&gt; = t2;
      C_2_basic_times&lt;span class="paren4"&gt;(&lt;span class="default"&gt;4,av2&lt;/span&gt;)&lt;/span&gt;;
    &lt;/span&gt;}&lt;/span&gt;
  &lt;/span&gt;}&lt;/span&gt; &lt;span class="symbol"&gt;else&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    &lt;span class="comment"&gt;/* Allocate continuation of (add1 i), which is the first part (f_253) */&lt;/span&gt;
    t3=&lt;span class="paren3"&gt;(&lt;span class="default"&gt;*a = C_CLOSURE_TYPE|3, a&lt;span class="paren4"&gt;[&lt;span class="default"&gt;1&lt;/span&gt;]&lt;/span&gt; = &lt;span class="paren4"&gt;(&lt;span class="default"&gt;C_word&lt;/span&gt;)&lt;/span&gt;f_253,
        a&lt;span class="paren4"&gt;[&lt;span class="default"&gt;2&lt;/span&gt;]&lt;/span&gt; = &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;C_word*&lt;/span&gt;)&lt;/span&gt;t0&lt;/span&gt;)&lt;/span&gt;&lt;span class="paren4"&gt;[&lt;span class="default"&gt;2&lt;/span&gt;]&lt;/span&gt;, a&lt;span class="paren4"&gt;[&lt;span class="default"&gt;3&lt;/span&gt;]&lt;/span&gt; = t1, tmp = &lt;span class="paren4"&gt;(&lt;span class="default"&gt;C_word&lt;/span&gt;)&lt;/span&gt;a, a += 4, tmp&lt;/span&gt;)&lt;/span&gt;;
    C_trace&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;test.scm:6: add1&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
    &lt;span class="paren3"&gt;{&lt;span class="default"&gt;
      C_word av2&lt;span class="paren4"&gt;[&lt;span class="default"&gt;4&lt;/span&gt;]&lt;/span&gt;;
      av2&lt;span class="paren4"&gt;[&lt;span class="default"&gt;0&lt;/span&gt;]&lt;/span&gt; = C_SCHEME_UNDEFINED;
      av2&lt;span class="paren4"&gt;[&lt;span class="default"&gt;1&lt;/span&gt;]&lt;/span&gt; = t3;
      av2&lt;span class="paren4"&gt;[&lt;span class="default"&gt;2&lt;/span&gt;]&lt;/span&gt; = t2;
      av2&lt;span class="paren4"&gt;[&lt;span class="default"&gt;3&lt;/span&gt;]&lt;/span&gt; = C_fix&lt;span class="paren4"&gt;(&lt;span class="default"&gt;1&lt;/span&gt;)&lt;/span&gt;;
      C_2_basic_plus&lt;span class="paren4"&gt;(&lt;span class="default"&gt;4,av2&lt;/span&gt;)&lt;/span&gt;;
    &lt;/span&gt;}&lt;/span&gt;
  &lt;/span&gt;}&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;As you can imagine, allocating a continuation on the stack every time is pretty heavy, and function calling isn't as cheap as a &lt;tt&gt;goto&lt;/tt&gt; loop either.  The first part of the loop doesn't even &lt;i&gt;do&lt;/i&gt; anything. It just acts as a continuation to be received by the &lt;tt&gt;plus&lt;/tt&gt; call. You can probably imagine how terrible the code would look if we compiled something like &lt;tt&gt;(/ (* (+ a b) (+ c d)) 2)&lt;/tt&gt;.  That's at least 4 continuations, instead of a few simple statements.&lt;/p&gt;
&lt;p&gt;For this reason, my patch was rejected (and rightly so!). The message was clear: code that doesn't use bignums should never pay a performance penalty just because bignums exist.&lt;/p&gt;
&lt;p&gt;In order to fix this situation, I had to come up with a radical change to how bignums worked, or face the possibility that a full numeric tower would not make it into CHICKEN 5.&lt;/p&gt;&lt;a href="#adding-a-new-scratch-space-memory-region"&gt;
&lt;h3 id="adding-a-new-scratch-space-memory-region"&gt;Adding a new &amp;quot;scratch space&amp;quot; memory region&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;If we want to make the extended numeric operators as fast as the originals, we &lt;b&gt;must&lt;/b&gt; be able to inline them.  This prevents garbage collection, because we don't get the continuation for an inlined call.  But what if they allocate some unknown quantity of memory?  We can't allocate on the stack or heap, because that could cause either to fill up, requiring a GC.&lt;/p&gt;
&lt;p&gt;So, the obvious solution is to allocate these objects &lt;i&gt;elsewhere&lt;/i&gt;. A separate memory space in which bignums can be stored.  But what if that space fills up?  Don't we need to initiate a GC then?  But this is where we're in luck: bignums are not compound objects!  They are huge slabs of opaque data, much like strings.  Because they can't refer to &lt;i&gt;other&lt;/i&gt; objects, we are dealing with a simplified garbage collection problem: only the objects pointing &lt;i&gt;to&lt;/i&gt; a bignum need to be updated.&lt;/p&gt;
&lt;p&gt;Unfortunately, finding all the live objects that point to a bignum would be quite difficult.  Luckily, like many problems in computer science, this can be easily solved by adding another level of indirection.  While we're calling inline functions, we can allocate small objects on the stack, which will remain there, never moving until the next GC.  We can use this to our advantage: whenever a bignum is needed, we allocate a fixed-size wrapper object on the stack.  This object points into the scratch space, where the actual bignum data lives.  See the following diagram:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/scratchspace-indirection.svg" /&gt;&lt;/p&gt;
&lt;p&gt;In the diagram, we have a bignum representing the number &lt;tt&gt;24386824307922&lt;/tt&gt;, which we've put in a list and a vector, and we also have the rational number &lt;tt&gt;1/24386824307922&lt;/tt&gt;, which refers to the same bignum in its denominator.  All these objects can be on the stack or on the heap.  We have no control over them; the user can set any object slot to hold the bignum.  We do have control over the wrapper object, and only the wrapper object directly points into scratch space.  Because bignums are opaque objects in Scheme, the wrapper is invisible.  Thus, user code is (in principle) unable to access the wrapper's data slot, so there will be no direct references to the bignum data portion.  This means we're free to move it around without updating anything but the wrapper object's slot.&lt;/p&gt;
&lt;p&gt;Note that in the scratch space, we also store a &lt;i&gt;back-pointer&lt;/i&gt; to the wrapper object's slot.  This allows us to update the wrapper object after moving its matching bignum data blob around.  This way, we can reallocate the scratch space when more space is needed.&lt;/p&gt;
&lt;p&gt;Some of the native functions like Karatsuba multiplication or Burnikel-Ziegler division generate many temporary values.  All such hand-written code has been tuned to erase a bignum's back-pointer when that bignum is no longer needed.  It makes the code quite a bit hairier, but it allows (limited) garbage collection to be done when reallocating the scratch space.&lt;/p&gt;
&lt;p&gt;With this setup, all numeric operations only need to allocate memory to hold a bignum wrapper object.  This is a fixed size, much like in CHICKEN 4, and it means numeric operations can once again be inlined!&lt;/p&gt;
&lt;p&gt;Oh, and why a bignum takes up 5 words?  Well, sometimes we know that a procedure receives 2 fixnums.  In that case, we can pre-allocate a bignum for the case when it overflows.  Because we know in its maximum size in advance, there's no need for the scratch space; we can just allocate it in the nursery.  For uniformity reasons, such a bignum still requires a wrapper object (2 words) and a bignum data blob (3 words: its header, the sign and one limb).  This sounds complicated, but it shortens the specialised code for two fixnums, and allocating only in the nursery is also faster.&lt;/p&gt;&lt;a href="#some-parting-thoughts"&gt;
&lt;h2 id="some-parting-thoughts"&gt;Some parting thoughts&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Adding full numeric tower support has been extremely educational for me.  I'm not really a math person, but having a clear goal like this motivated me to dive in deep into the literature.  Overall, I'm happy with how it turned out, but there are always improvements.&lt;/p&gt;
&lt;p&gt;For example, instead of doing everything in C it would (of course!) be preferable to do it all in Scheme.  Unfortunately, CHICKEN's design makes it hard to do this in an efficient way: it's currently impossible to export Scheme procedures that can be called inline (i.e., non-CPS calls) without copying their full code into the call site.  If we can find a way, it would be possible to do 90% of the algorithms in Scheme.  The principle on which this would be based can be found in an &lt;a href="http://dl.acm.org/citation.cfm?doid=319838.319861" class="external"&gt;old paper about the Lucid Common Lisp implementation&lt;/a&gt;.  Basically, you implement a handful of primitives natively, and everything else can be done in Lisp.  For example, SBCL is implemented this way too.&lt;/p&gt;
&lt;p&gt;As far as I can tell, of the more popular Scheme implementations, Gambit is the only one that actually does this.  I've been very impressed with Gambit in general.  Besides having pretty readable Scheme code for bignum algorithms, Gambit has some superior bignum algorithms, most get close to (and in rare cases even surpass) GMP performance.  This is mostly due to the hard work of &lt;a href="http://www.math.purdue.edu/~lucier/" class="external"&gt;Bradley Lucier&lt;/a&gt;, a numerical analyst who has also provided useful feedback on some of my work on the numbers egg, and this series of blog posts.  He &lt;i&gt;really&lt;/i&gt; knows this stuff!  Most other Scheme implementations are in C and still pretty slow due to the algorithms they use, unless of course they use GMP.&lt;/p&gt;
&lt;p&gt;In CHICKEN, there is a lot of room for optimisations.  But I also think we shouldn't try to implement every algorithm under the sun. Things should generally be fast enough to serve the most common cases. Typical code doesn't use bignums, and if it does it's only small bignums (for instance, when using 64-bit integers with the FFI), which is why I think we should optimise for these cases.  For example, my implementations of Karatsuba and Burnikel-Ziegler aren't great, so if anyone feels like having a stab at improving these things we already have (or simply replacing them with a better algorithm), please do!&lt;/p&gt;&lt;a href="#references"&gt;
&lt;h2 id="references"&gt;References&lt;/h2&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Jon L White, &lt;a href="http://dl.acm.org/citation.cfm?doid=319838.319861" class="external"&gt;Reconfigurable, Retargetable Bignums: A Case Study in Efficient, Portable Lisp System Building&lt;/a&gt; (or &lt;a href="http://sci-hub.cc/10.1145/319838.319861" class="external"&gt;via Sci-Hub&lt;/a&gt;).  This is a wonderful 1986(!) paper how to elegantly have bignum algorithms in pure Lisp with a minimal amount of native code to get good performance.&lt;/li&gt;
&lt;li&gt;After writing the scratch space stuff, I sent a mail to chicken-hackers &lt;a href="http://lists.gnu.org/archive/html/chicken-hackers/2015-04/msg00038.html" class="external"&gt;explaining how it works&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;There's a Larceny note that mentions &lt;a href="http://www.ccs.neu.edu/home/lth/larceny/notes/note2-repr.html#numbers" class="external"&gt;how numbers are represented&lt;/a&gt; in Larceny, and a note that briefly mentions &lt;a href="http://www.cs.northeastern.edu/home/lth/larceny/notes/note3-arithmetic.html#bignums" class="external"&gt;that it also uses the &amp;quot;retargetable&amp;quot; bignum approach&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Gambit's source code is &lt;a href="https://github.com/gambit/gambit/blob/c65e6b33d2d81e7abc4df35c6d49ecce52d7930f/lib/_num.scm#L5546" class="external"&gt;extensively commented&lt;/a&gt; on representation and algorithms used.&lt;/li&gt;&lt;/ul&gt;</content>
    <id>tag:more-magic,2016-10-20:/posts/numeric-tower-part-5.html</id>
    <published>2016-10-20T18:01:20Z</published>
    <title type="text">CHICKEN's numeric tower: part 5</title>
    <updated>2016-10-20T18:01:20Z</updated>
    <link href="https://www.more-magic.net/posts/numeric-tower-part-5.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;In this instalment of the blog series, we'll take a look at how &lt;tt&gt;string-&amp;gt;number&lt;/tt&gt; and &lt;tt&gt;number-&amp;gt;string&lt;/tt&gt; are implemented for bignums.&lt;/p&gt;&lt;a href="#performing-base-conversions"&gt;
&lt;h2 id="performing-base-conversions"&gt;Performing base conversions&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Performing calculations is all nice and useful, but you eventually want to print the results back to the user.  And of course the user needs a way to enter such large numbers into the system.  So, converting between numbers and strings is an essential operation.  The Scheme standard requires support for conversion &lt;a href="http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2.6" class="external"&gt;between bases 2, 8, 10 and 16&lt;/a&gt;, but many practical implementations support conversion between arbitrary bases, and why not?  It doesn't really require more effort.&lt;/p&gt;&lt;a href="#converting-strings-to-numbers"&gt;
&lt;h3 id="converting-strings-to-numbers"&gt;Converting strings to numbers&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Let's start with the simpler of the two directions: &lt;tt&gt;string-&amp;gt;number&lt;/tt&gt;.  The naive way of converting a string in base &lt;tt&gt;n&lt;/tt&gt; to a number is to scan the string from left to right (high to low), adding the digit to the result and multiplying the result by &lt;tt&gt;n&lt;/tt&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="comment"&gt;/* &amp;quot;result&amp;quot; is a pre-allocated, zeroed out bignum of the right size */&lt;/span&gt;
&lt;span class="symbol"&gt;while&lt;/span&gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;*str != &lt;span class="character"&gt;&amp;#x27;0&amp;#x27;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="comment"&gt;/* Assuming NUL-terminated string */&lt;/span&gt;
&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  &lt;span class="symbol"&gt;int&lt;/span&gt; digit = hex_char_to_digit&lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="symbol"&gt;int&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;*str++&lt;/span&gt;)&lt;/span&gt;;
  bignum_destructive_scale_up&lt;span class="paren2"&gt;(&lt;span class="default"&gt;result, radix&lt;/span&gt;)&lt;/span&gt;;
  bignum_destructive_add&lt;span class="paren2"&gt;(&lt;span class="default"&gt;result, digit&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This is very simple and elegant, but also quite slow.  The Scheme48 code also checks for invalid characters in this loop, while in CHICKEN, the reader performs this check.  So, when converting a digit stream to a bignum, we already know the digit stream contains only valid digits.&lt;/p&gt;
&lt;p&gt;A simple improvement can be made to this algorithm: we can avoid traversing the entire bignum for every string digit.  Instead, we collect multiple digits in a register until we fill up a halfword. Then, we scale up the bignum, adding the collected halfword:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="symbol"&gt;do&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  C_word big_digit = 0;  &lt;span class="comment"&gt;/* Collected digit */&lt;/span&gt;
  C_word factor = radix; &lt;span class="comment"&gt;/* Multiplication factor for bignum */&lt;/span&gt;

  &lt;span class="comment"&gt;/* Keep collecting from str while factor fits a half-digit */&lt;/span&gt;
  &lt;span class="symbol"&gt;while&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;str &amp;lt; str_end &amp;amp;&amp;amp; C_fitsinbignumhalfdigitp&lt;span class="paren3"&gt;(&lt;span class="default"&gt;factor&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    str_digit = hex_char_to_digit&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="symbol"&gt;int&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;*str++&lt;/span&gt;)&lt;/span&gt;;
    factor *= radix;
    big_digit = radix * big_digit + str_digit;
  &lt;/span&gt;}&lt;/span&gt;

  &lt;span class="comment"&gt;/* Scaling up with carry avoids traversing bignum twice */&lt;/span&gt;
  big_digit = bignum_digits_destructive_scale_up_with_carry&lt;span class="paren2"&gt;(&lt;span class="default"&gt;
                digits, last_digit, factor / radix, big_digit&lt;/span&gt;)&lt;/span&gt;;

  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;big_digit&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt; &lt;span class="comment"&gt;/* If there was a carry, increment size of bignum */&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;*last_digit++&lt;/span&gt;)&lt;/span&gt; = big_digit;
  &lt;/span&gt;}&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt; &lt;span class="symbol"&gt;while&lt;/span&gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;str &amp;lt; str_end&lt;/span&gt;)&lt;/span&gt;;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Remember the previous post in this series?  Now you know where the design behind &lt;tt&gt;bignum_digits_destructive_scale_up_with_carry&lt;/tt&gt; comes from: we can scale up the bignum with an initial &amp;quot;carry&amp;quot; value that's our collected digit.  The return value is the resulting carry (if any), so we know when to increase the bignum's size by moving the &lt;tt&gt;last_digit&lt;/tt&gt; pointer.  This pointer makes it easier to detect the final length of the bignum, which can be hard to predict precisely. We can't predict the &lt;i&gt;exact&lt;/i&gt; size, but we can calculate the &lt;i&gt;maximum&lt;/i&gt; size.  Because we allocate this maximum size, this moving of the end pointer is safe.&lt;/p&gt;
&lt;p&gt;If the string's base is a power of two, we can perform an even better optimisation: We don't need to multiply or add to the bignum, we can just write straight to the bignum's digits!&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="symbol"&gt;int&lt;/span&gt; radix_shift = C_ilen&lt;span class="paren1"&gt;(&lt;span class="default"&gt;radix&lt;/span&gt;)&lt;/span&gt; - 1;  &lt;span class="comment"&gt;/* Integer length (the power of two) */&lt;/span&gt;
C_uword big_digit = 0;       &lt;span class="comment"&gt;/* The current bignum digit being constructed */&lt;/span&gt;
&lt;span class="symbol"&gt;int&lt;/span&gt; n = 0;                &lt;span class="comment"&gt;/* The number of bits read so far into big_digit */&lt;/span&gt;

&lt;span class="comment"&gt;/* Read from least to most significant digit.  This is much easier! */&lt;/span&gt;
&lt;span class="symbol"&gt;while&lt;/span&gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;str_end &amp;gt; str_start&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  str_digit = hex_char_to_digit&lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="symbol"&gt;int&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;*--str_end&lt;/span&gt;)&lt;/span&gt;;

  big_digit |= &lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_uword&lt;/span&gt;)&lt;/span&gt;str_digit &amp;lt;&amp;lt; n;
  n += radix_shift;                             &lt;span class="comment"&gt;/* Processed n bits so far */&lt;/span&gt;

  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;n &amp;gt;= C_BIGNUM_DIGIT_LENGTH&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;             &lt;span class="comment"&gt;/* Filled up the digit? */&lt;/span&gt;
    n -= C_BIGNUM_DIGIT_LENGTH;                 &lt;span class="comment"&gt;/* Number of remainder bits */&lt;/span&gt;
    *digits++ = big_digit;
    big_digit = str_digit &amp;gt;&amp;gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;radix_shift - n&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* Keep only the remainder */&lt;/span&gt;
  &lt;/span&gt;}&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;
&lt;span class="comment"&gt;/* If radix isn&amp;#x27;t an exact divisor of digit length, write final remainder */&lt;/span&gt;
&lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;n &amp;gt; 0&lt;/span&gt;)&lt;/span&gt; *digits++ = big_digit;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;From my benchmarks it looks like CHICKEN's &lt;tt&gt;string-&amp;gt;number&lt;/tt&gt; implementation is among the fastest of the popular Scheme implementations for power of two bases, due to this bit banging loop.&lt;/p&gt;&lt;a href="#converting-numbers-to-strings"&gt;
&lt;h3 id="converting-numbers-to-strings"&gt;Converting numbers to strings&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;The naive way of converting a number to a string in base &lt;tt&gt;n&lt;/tt&gt; is to do the opposite of converting a string in base &lt;tt&gt;n&lt;/tt&gt; to a number: we repeatedly divide by the target base and prepend this number to the string.&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="symbol"&gt;char&lt;/span&gt; *characters = &lt;span class="string"&gt;&amp;quot;0123456789abcdef&amp;quot;&lt;/span&gt;;

&lt;span class="comment"&gt;/* This fills the &amp;quot;buf&amp;quot; array *back to front*, so index starts at the
 * end of &amp;quot;buf&amp;quot;.  counter represents # of characters written.
 */&lt;/span&gt;
&lt;span class="symbol"&gt;do&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  digit = bignum_destructive_scale_down&lt;span class="paren2"&gt;(&lt;span class="default"&gt;working_copy, radix&lt;/span&gt;)&lt;/span&gt;;
  *index-- = characters&lt;span class="paren2"&gt;[&lt;span class="default"&gt;digit&lt;/span&gt;]&lt;/span&gt;;

  &lt;span class="comment"&gt;/* If we reached the current string&amp;#x27;s length, reallocate in
   * increments of BIGNUM_STR_BLOCK_SIZE.
   */&lt;/span&gt;
  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;++counter == len&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
   &lt;span class="symbol"&gt;char&lt;/span&gt; *newbuf = C_malloc&lt;span class="paren3"&gt;(&lt;span class="default"&gt;len + BIGNUM_STR_BLOCK_SIZE&lt;/span&gt;)&lt;/span&gt;;
   &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;newbuf == NULL&lt;/span&gt;)&lt;/span&gt; &lt;span class="symbol"&gt;return&lt;/span&gt; ERR;

   C_memcpy&lt;span class="paren3"&gt;(&lt;span class="default"&gt;newbuf + BIGNUM_STR_BLOCK_SIZE, buf, len&lt;/span&gt;)&lt;/span&gt;;
   C_free&lt;span class="paren3"&gt;(&lt;span class="default"&gt;buf&lt;/span&gt;)&lt;/span&gt;;
   buf = newbuf;
   index = newbuf + BIGNUM_STR_BLOCK_SIZE - 1;
   len += BIGNUM_STR_BLOCK_SIZE;
&lt;/span&gt;}&lt;/span&gt; &lt;span class="symbol"&gt;while&lt;/span&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;bignum_length&lt;span class="paren3"&gt;(&lt;span class="default"&gt;working_copy&lt;/span&gt;)&lt;/span&gt; &amp;gt; 0&lt;/span&gt;)&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This is the original version as provided by Scheme48.  Again, it's very short and clean.  It operates on a copy of the bignum, which it destructively scales down by dividing it by &lt;tt&gt;radix&lt;/tt&gt;.  The remainder digit is written to the string after conversion to a character.  Many implementations use this algorithm, but it can be improved pretty easily, in basically the same way we improved the reverse operation. Instead of dividing by the radix on ever loop iteration, you can chop off a big lump.  This is the remainder of dividing by a large number.  Then, you divide this remainder in a loop while emitting string digits until you hit zero, then repeat until the bignum is zero.&lt;/p&gt;
&lt;p&gt;Another improvement over the Scheme48 code is that you can pre-calculate a (pessimistic) upper bound on the number of digits, so you can avoid the reallocation (which implies a memory copy).  For powers of two, this can be done precisely.  For other radixes you can shorten the buffer only once at the end, and only if it turns out to be necessary.&lt;/p&gt;
&lt;p&gt;This is really very simple, except for the finishing up part, where we shorten the buffer:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="symbol"&gt;int&lt;/span&gt; steps;
C_uword base;         &lt;span class="comment"&gt;/* This is the &amp;quot;lump&amp;quot; we cut off every time (divisor) */&lt;/span&gt;
C_uword *scan = start + C_bignum_size&lt;span class="paren1"&gt;(&lt;span class="default"&gt;bignum&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* Start scanning at the end */&lt;/span&gt;

&lt;span class="comment"&gt;/* Calculate the largest power of radix (string base) that fits a halfdigit.
 * If radix is 10, steps = log10(2^halfdigit_bits), base = 10^steps
 */&lt;/span&gt;
&lt;span class="symbol"&gt;for&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;steps = 0, base = radix; C_fitsinbignumhalfdigitp&lt;span class="paren2"&gt;(&lt;span class="default"&gt;base&lt;/span&gt;)&lt;/span&gt;; base *= radix&lt;/span&gt;)&lt;/span&gt;
  steps++;

base /= radix; &lt;span class="comment"&gt;/* Back down: we always overshoot in the loop by one step */&lt;/span&gt;

&lt;span class="symbol"&gt;while&lt;/span&gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;scan &amp;gt; start&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  &lt;span class="comment"&gt;/* Divide by base. This chops &amp;quot;steps&amp;quot; string digits off of the bignum */&lt;/span&gt;
  big_digit = bignum_digits_destructive_scale_down&lt;span class="paren2"&gt;(&lt;span class="default"&gt;start, scan, base&lt;/span&gt;)&lt;/span&gt;;

  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;*&lt;span class="paren3"&gt;(&lt;span class="default"&gt;scan-1&lt;/span&gt;)&lt;/span&gt; == 0&lt;/span&gt;)&lt;/span&gt; scan--; &lt;span class="comment"&gt;/* Adjust if we exhausted the highest digit */&lt;/span&gt;

  &lt;span class="symbol"&gt;for&lt;/span&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;i = 0; i &amp;lt; steps &amp;amp;&amp;amp; index &amp;gt;= buf; ++i&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;      &lt;span class="comment"&gt;/* Emit string digits */&lt;/span&gt;
    C_uword tmp = big_digit / radix;
    *index-- = characters&lt;span class="paren3"&gt;[&lt;span class="default"&gt;big_digit - &lt;span class="paren4"&gt;(&lt;span class="default"&gt;tmp*radix&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;]&lt;/span&gt;; &lt;span class="comment"&gt;/* big_digit % radix */&lt;/span&gt;
    big_digit = tmp;
  &lt;/span&gt;}&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;

&lt;span class="comment"&gt;/* Move index onto first nonzero digit.  We&amp;#x27;re writing a bignum
   here: it can&amp;#x27;t consist of only zeroes. */&lt;/span&gt;
&lt;span class="symbol"&gt;while&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;*++index == &lt;span class="character"&gt;&amp;#x27;0&amp;#x27;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;

&lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;negp&lt;/span&gt;)&lt;/span&gt; *--index = &lt;span class="character"&gt;&amp;#x27;-&amp;#x27;&lt;/span&gt;;

&lt;span class="comment"&gt;/* Shorten with distance between start and index. */&lt;/span&gt;
&lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;buf != index&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  i = C_header_size&lt;span class="paren2"&gt;(&lt;span class="default"&gt;string&lt;/span&gt;)&lt;/span&gt; - &lt;span class="paren2"&gt;(&lt;span class="default"&gt;index - buf&lt;/span&gt;)&lt;/span&gt;;
  C_memmove&lt;span class="paren2"&gt;(&lt;span class="default"&gt;buf, index, i&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* Move start of number to beginning. */&lt;/span&gt;
  C_block_header&lt;span class="paren2"&gt;(&lt;span class="default"&gt;string&lt;/span&gt;)&lt;/span&gt; = C_STRING_TYPE | i; &lt;span class="comment"&gt;/* Mutate strlength. */&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Finally, if the radix is a power of two, we can do a straight bit-to-bit extraction like we did with &lt;tt&gt;string-&amp;gt;number&lt;/tt&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="symbol"&gt;int&lt;/span&gt; radix_shift = C_ilen&lt;span class="paren1"&gt;(&lt;span class="default"&gt;radix&lt;/span&gt;)&lt;/span&gt; - 1;    &lt;span class="comment"&gt;/* Integer length (the power of two) */&lt;/span&gt;
&lt;span class="symbol"&gt;int&lt;/span&gt; radix_mask = radix - 1;              &lt;span class="comment"&gt;/* Bitmask of N-1 ones (radix = 2ᴺ) */&lt;/span&gt;

&lt;span class="comment"&gt;/* Again, we go from least significant to most significant digit */&lt;/span&gt;
&lt;span class="symbol"&gt;while&lt;/span&gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;scan &amp;lt; end&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  C_uword big_digit = *scan++;
  &lt;span class="symbol"&gt;int&lt;/span&gt; big_digit_len = C_BIGNUM_DIGIT_LENGTH;

  &lt;span class="symbol"&gt;while&lt;/span&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;big_digit_len &amp;gt; 0 &amp;amp;&amp;amp; index &amp;gt;= buf&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    &lt;span class="symbol"&gt;int&lt;/span&gt; radix_digit = big_digit &amp;amp; radix_mask;    &lt;span class="comment"&gt;/* Extract one string digit */&lt;/span&gt;
    *index-- = characters&lt;span class="paren3"&gt;[&lt;span class="default"&gt;radix_digit&lt;/span&gt;]&lt;/span&gt;; &lt;span class="comment"&gt;/* Write it (as character) to string */&lt;/span&gt;
    big_digit &amp;gt;&amp;gt;= radix_shift;                            &lt;span class="comment"&gt;/* Drop this digit */&lt;/span&gt;
    big_digit_len -= radix_shift;
  &lt;/span&gt;}&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Unfortunately, there are some caveats that make this slightly trickier than you would guess.  The above code is simplified, and only works for some radixes.  If your radix is &lt;tt&gt;2ⁿ&lt;/tt&gt;, and your base digit size is &lt;tt&gt;2ᵐ&lt;/tt&gt; bits, then this code works if &lt;tt&gt;m&lt;/tt&gt; is a multiple of &lt;tt&gt;n&lt;/tt&gt;. Otherwise, you'll need to take care of overlaps.  Octal numbers are the biggest problem here, because they're 3 bits per string digit and the bignum digit sizes of 32 or 64 bits don't divide cleanly by 3.&lt;/p&gt;
&lt;p&gt;Getting this right complicates the algorithm enough to make it slightly too hairy to present here (there's some more shifting and &lt;tt&gt;if&lt;/tt&gt; checks involved).  If you're interested how to handle this, you can always study the CHICKEN sources.&lt;/p&gt;&lt;a href="#divide-and-conquer"&gt;
&lt;h4 id="divide-and-conquer"&gt;Divide and conquer&lt;/h4&gt;&lt;/a&gt;
&lt;p&gt;Because of the many divisions, &lt;tt&gt;number-&amp;gt;string&lt;/tt&gt; is much slower than &lt;tt&gt;string-&amp;gt;number&lt;/tt&gt;.  Luckily, we can speed up the former by relying once again on a recursive divide and conquer style algorithm.&lt;/p&gt;
&lt;p&gt;This requires you to know the string's expected size in the target base, and will divide the number by half that.  For example, if you wish to convert the number &lt;tt&gt;12345678&lt;/tt&gt; to a decimal string, you can decide to split it in two.  If you had a perfect guess of the string's length (which is 8), you can split the expected string in two halves by dividing the number by &lt;tt&gt;10⁴&lt;/tt&gt;, or &lt;tt&gt;10000&lt;/tt&gt;, giving us the quotient &lt;tt&gt;1234&lt;/tt&gt; and the remainder &lt;tt&gt;5678&lt;/tt&gt;.  These can recursively be converted to a string and finally appended together.  Note that if you have a pessimistic upper limit of the final string length, it'll be slower, but will still produce a correct result.  The code for this is quite straightforward:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;integer-&amp;gt;string/recursive n base expected-string-size&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;let*-values &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;halfsize&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;fxshr &lt;span class="paren6"&gt;(&lt;span class="default"&gt;fx+ expected-string-size 1&lt;/span&gt;)&lt;/span&gt; 1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;b^M/2&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;integer-power base halfsize&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;hi lo&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;quotient&amp;amp;remainder n b^M/2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;strhi&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;number-&amp;gt;string hi base&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;strlo&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;number-&amp;gt;string &lt;span class="paren6"&gt;(&lt;span class="default"&gt;abs lo&lt;/span&gt;)&lt;/span&gt; base&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;string-append strhi
                   &lt;span class="comment"&gt;;; Fix up any leading zeroes that were stripped from strlo
&lt;/span&gt;                   &lt;span class="paren4"&gt;(&lt;span class="default"&gt;make-string &lt;span class="paren5"&gt;(&lt;span class="default"&gt;fx- halfsize &lt;span class="paren6"&gt;(&lt;span class="default"&gt;string-length strlo&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="character"&gt;#\0&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                   strlo&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Because the number &lt;tt&gt;120034&lt;/tt&gt;, when split in two, generates &lt;tt&gt;120&lt;/tt&gt; and &lt;tt&gt;34&lt;/tt&gt;, we need the &lt;tt&gt;make-string&lt;/tt&gt; call to add back the leading zeroes, otherwise we would get &lt;tt&gt;12034&lt;/tt&gt; as the output.  This can be omitted if you have a more low-level &lt;tt&gt;number-&amp;gt;string&lt;/tt&gt; implementation which &lt;i&gt;doesn't&lt;/i&gt; truncate leading zeroes.&lt;/p&gt;
&lt;p&gt;While I was researching this, I found out about a technique called the &amp;quot;scaled remainder tree&amp;quot; algorithm.  This algorithm is supposedly even faster than the simple recursive algorithm I just showed you. Unfortunately, I was unable to wrap my head around it.  Maybe you will have better luck!&lt;/p&gt;&lt;a href="#reading-list"&gt;
&lt;h2 id="reading-list"&gt;Reading list&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;There doesn't seem to be that much information on how to efficiently perform base conversion, even though there are quite a few clever implementation techniques out there.  If you spend the time searching, you'll be sure to find some gems.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;a href="http://www.numberworld.org/y-cruncher/internals/radix-conversion.html" class="external"&gt;y-cruncher page on radix conversion&lt;/a&gt; is full of ideas.  Y-cruncher is a program to calculate digits of pi by efficiently using multiple CPU cores.  This page has several algorithms, including recursive string splitting and scaled remainder tree.  Unfortunately, the program itself is proprietary so you can't study its implementations of these algorithms.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://members.loria.fr/PZimmermann/mca/pub226.html" class="external"&gt;Modern Computer Arithmetic&lt;/a&gt;, which has quickly become my favourite bignum textbook, has an interesting alternative string to number technique based on iterative multiplication of the input string.  I still want to try that out some day.  It also hints at scaled remainder tree for number to string conversion, but doesn't explain how it works.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hal.inria.fr/hal-00864293v1/document" class="external"&gt;Division-Free Binary-to-Decimal Conversion&lt;/a&gt; by Cyril Bouvier and Paul Zimmermann explains a number to string conversion based on the scaled remainder tree.  Unfortunately, this paper only confused me.&lt;/li&gt;
&lt;li&gt;It looks like Gambit has a &lt;a href="https://github.com/gambit/gambit/blob/master/lib/_num.scm#L3999" class="external"&gt;recursive divide-and-conquer implementation of &lt;tt&gt;string-&amp;gt;number&lt;/tt&gt;&lt;/a&gt; that's slightly different from ours.  Their &lt;a href="https://github.com/gambit/gambit/blob/master/lib/_num.scm#L3460" class="external"&gt;recursive &lt;tt&gt;number-&amp;gt;string&lt;/tt&gt; implementation&lt;/a&gt; is rather interesting too.&lt;/li&gt;&lt;/ul&gt;</content>
    <id>tag:more-magic,2016-10-18:/posts/numeric-tower-part-4.html</id>
    <published>2016-10-18T17:42:03Z</published>
    <title type="text">CHICKEN's numeric tower: part 4</title>
    <updated>2016-10-18T17:42:03Z</updated>
    <link href="https://www.more-magic.net/posts/numeric-tower-part-4.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;Now that you understand the basic bignum algorithms, let's look at various tricks to speed up these operations.&lt;/p&gt;&lt;a href="#faster-multiplication"&gt;
&lt;h2 id="faster-multiplication"&gt;Faster multiplication&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Like I mentioned in the previous part of this series, the primary school method for addition and subtraction is the fastest known, for bignums of any size.  And you can't really get better than &lt;tt&gt;O(n)&lt;/tt&gt;. However, primary school multiplication is &lt;tt&gt;O(n²)&lt;/tt&gt;, and there are &lt;i&gt;several&lt;/i&gt; better algorithms than that.&lt;/p&gt;&lt;a href="#multiplication-by-a-fixnum"&gt;
&lt;h3 id="multiplication-by-a-fixnum"&gt;Multiplication by a fixnum&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;As you now know, multiplication is done by looping over the half-digits of the two bignum arguments in a nested loop.  Nested loops are something to be avoided as much as possible, because this means you're looking at a quadratic time algorithm, in other words it will perform &lt;tt&gt;O(n²)&lt;/tt&gt; operations.&lt;/p&gt;
&lt;p&gt;When multiplying a bignum by a fixnum, the naive implementation is to &amp;quot;promote&amp;quot; the fixnum into a bignum, and then perform a standard bignum multiplication.  However, if the fixnum fits in a half-digit, you can avoid the nested loop.  Complexity-wise, this isn't a great improvement, as the outer loop is only run once anyway.  But, because the small value fits in a machine word, you only read from one bignum address instead of two on every iteration of the inner loop.  Now that makes a big difference!  In Scheme48, this improved algorithm looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="symbol"&gt;static&lt;/span&gt; &lt;span class="symbol"&gt;void&lt;/span&gt;
bignum_destructive_scale_up&lt;span class="paren1"&gt;(&lt;span class="default"&gt;bignum_type bignum, bignum_digit_type factor&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  bignum_digit_type carry = 0;
  bignum_digit_type * scan = &lt;span class="paren2"&gt;(&lt;span class="default"&gt;BIGNUM_START_PTR &lt;span class="paren3"&gt;(&lt;span class="default"&gt;bignum&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
  bignum_digit_type two_digits;
  bignum_digit_type product_low;
&lt;span class="special"&gt;#define product_high carry
&lt;/span&gt;  bignum_digit_type * end = &lt;span class="paren2"&gt;(&lt;span class="default"&gt;scan + &lt;span class="paren3"&gt;(&lt;span class="default"&gt;BIGNUM_LENGTH &lt;span class="paren4"&gt;(&lt;span class="default"&gt;bignum&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
  BIGNUM_ASSERT &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;factor &amp;gt; 1&lt;/span&gt;)&lt;/span&gt; &amp;amp;&amp;amp; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;factor &amp;lt; BIGNUM_RADIX_ROOT&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
  &lt;span class="symbol"&gt;while&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;scan &amp;lt; end&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
      two_digits = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;*scan&lt;/span&gt;)&lt;/span&gt;;
      product_low = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;factor * &lt;span class="paren5"&gt;(&lt;span class="default"&gt;HD_LOW &lt;span class="paren6"&gt;(&lt;span class="default"&gt;two_digits&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; + &lt;span class="paren4"&gt;(&lt;span class="default"&gt;HD_LOW &lt;span class="paren5"&gt;(&lt;span class="default"&gt;carry&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
      product_high =
        &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;factor * &lt;span class="paren5"&gt;(&lt;span class="default"&gt;HD_HIGH &lt;span class="paren6"&gt;(&lt;span class="default"&gt;two_digits&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; +
         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;HD_HIGH &lt;span class="paren5"&gt;(&lt;span class="default"&gt;product_low&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; +
         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;HD_HIGH &lt;span class="paren5"&gt;(&lt;span class="default"&gt;carry&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
      &lt;span class="paren3"&gt;(&lt;span class="default"&gt;*scan++&lt;/span&gt;)&lt;/span&gt; = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;HD_CONS &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;HD_LOW &lt;span class="paren6"&gt;(&lt;span class="default"&gt;product_high&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;, &lt;span class="paren5"&gt;(&lt;span class="default"&gt;HD_LOW &lt;span class="paren6"&gt;(&lt;span class="default"&gt;product_low&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
      carry = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;HD_HIGH &lt;span class="paren4"&gt;(&lt;span class="default"&gt;product_high&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
    &lt;/span&gt;}&lt;/span&gt;
  &lt;span class="comment"&gt;/* A carry here would be an overflow, i.e. it would not fit.
     Hopefully the callers allocate enough space that this will
     never happen.
   */&lt;/span&gt;
  BIGNUM_ASSERT &lt;span class="paren2"&gt;(&lt;span class="default"&gt;carry == 0&lt;/span&gt;)&lt;/span&gt;;
  return;
&lt;span class="special"&gt;#undef product_high
&lt;/span&gt;&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The current version of this algorithm in CHICKEN is a bit shorter and slightly more versatile because it returns the carry if the result doesn't fit:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="symbol"&gt;static&lt;/span&gt; C_uword bignum_digits_destructive_scale_up_with_carry&lt;span class="paren1"&gt;(&lt;span class="default"&gt;
    C_uword *start, C_uword *end, C_uword factor, C_uword carry&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  C_uword digit, p;

  assert&lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_fitsinbignumhalfdigitp&lt;span class="paren3"&gt;(&lt;span class="default"&gt;carry&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
  assert&lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_fitsinbignumhalfdigitp&lt;span class="paren3"&gt;(&lt;span class="default"&gt;factor&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;

  &lt;span class="symbol"&gt;while&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;start &amp;lt; end&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    digit = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;*start&lt;/span&gt;)&lt;/span&gt;;

    p = factor * C_BIGNUM_DIGIT_LO_HALF&lt;span class="paren3"&gt;(&lt;span class="default"&gt;digit&lt;/span&gt;)&lt;/span&gt; + carry;
    carry = C_BIGNUM_DIGIT_LO_HALF&lt;span class="paren3"&gt;(&lt;span class="default"&gt;p&lt;/span&gt;)&lt;/span&gt;;

    p = factor * C_BIGNUM_DIGIT_HI_HALF&lt;span class="paren3"&gt;(&lt;span class="default"&gt;digit&lt;/span&gt;)&lt;/span&gt; + C_BIGNUM_DIGIT_HI_HALF&lt;span class="paren3"&gt;(&lt;span class="default"&gt;p&lt;/span&gt;)&lt;/span&gt;;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;*start++&lt;/span&gt;)&lt;/span&gt; = C_BIGNUM_DIGIT_COMBINE&lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_BIGNUM_DIGIT_LO_HALF&lt;span class="paren4"&gt;(&lt;span class="default"&gt;p&lt;/span&gt;)&lt;/span&gt;, carry&lt;/span&gt;)&lt;/span&gt;;
    carry = C_BIGNUM_DIGIT_HI_HALF&lt;span class="paren3"&gt;(&lt;span class="default"&gt;p&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt;
  &lt;span class="symbol"&gt;return&lt;/span&gt; carry;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This is a destructive operation, which means it doesn't operate on an &amp;quot;empty&amp;quot; target bignum.  Instead, you copy the original bignum, which is then mutated in-place. That makes it faster because you're only reading and writing to a single digit array, so it's much more localised in memory.  In the next post, we'll see why returning the carry can be helpful.&lt;/p&gt;
&lt;p&gt;Strictly speaking, you could do the same for addition and subtraction: if one of the arguments is a bignum and the other a fixnum, you could destructively add or subtract it.  In fact, Scheme48 does this, but the CHICKEN implementation does not.  If you'll recall, the CHICKEN bignum implementation already copies the larger of the two numbers into a new bignum and modifies it in-place while adding the smaller number.  The effect of this is almost the same as Scheme48 does, while also improving the default case of adding two bignums.&lt;/p&gt;
&lt;p&gt;There's a second optimisation that can be done, which Scheme48 does not do at all.  If the factor by which we're multiplying is a power of two, you can simply &lt;i&gt;shift&lt;/i&gt; the result by the 2log of the factor! The code for detecting this is pretty ugly, so I'm not going to show it.  Just remember that this makes a huge difference in practice.&lt;/p&gt;&lt;a href="#karatsubas-multiplication"&gt;
&lt;h3 id="karatsubas-multiplication"&gt;Karatsuba's multiplication&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Multiplying two bignums can be done faster, too.  There are two important algorithms: Karatsuba multiplication and FFT-based multiplications like Schönhage-Strassen.  I must confess that my understanding of the FFT is too weak to implement, let alone explain the Schönhage-Strassen algorithm, so if you want to read about that, check the reading list at the end of this post.&lt;/p&gt;
&lt;p&gt;Luckily, the Karatsuba algorithm is easy to explain.  It was named after the Russian mathematician &lt;a href="https://en.wikipedia.org/wiki/Anatoly_Karatsuba" class="external"&gt;Anatoly Karatsuba&lt;/a&gt;, who was the first to reject the idea that &lt;tt&gt;O(n²)&lt;/tt&gt; is the best we can do.  His approach is based on divide and conquer.  It uses a simple algebraic trick to reduce work on each step.&lt;/p&gt;
&lt;p&gt;Let's say we want to multiply two bignums of two limbs, &lt;tt&gt;x[1,2]&lt;/tt&gt; and &lt;tt&gt;y[1,2]&lt;/tt&gt; in base &lt;tt&gt;B&lt;/tt&gt;. The result is of course &lt;tt&gt;xy&lt;/tt&gt;.  Rephrased as an equation:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; xy = (x₁·B + x₂) · (y₁·B + y₂)&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This can be written out as:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; xy = (x₁·y₁)·B² + (x₁·y₂ + x₂·y₁)·B + x₂·y₂&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;If we call these three components &lt;tt&gt;a&lt;/tt&gt;, &lt;tt&gt;b&lt;/tt&gt; and &lt;tt&gt;c&lt;/tt&gt;, then &lt;tt&gt;xy = a·B² + b·B + c&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Now, you can calculate all three components separately, but this requires exactly as many steps as the &amp;quot;school book&amp;quot; algorithm we already have, namely &lt;tt&gt;O(n²)&lt;/tt&gt;.  However, the crucial insight that Karatsuba had is that you can derive &lt;tt&gt;b&lt;/tt&gt; from &lt;tt&gt;a&lt;/tt&gt; and &lt;tt&gt;c&lt;/tt&gt; with a simpler multiplication.  He actually did this by first making it &lt;i&gt;more complex&lt;/i&gt;.  This shows the man's genius: complicating things to simplify them isn't exactly intuitive!  So we have &lt;tt&gt;a&lt;/tt&gt;, &lt;tt&gt;b&lt;/tt&gt; and &lt;tt&gt;c&lt;/tt&gt;:&lt;/p&gt;
&lt;style type="text/css"&gt;
.var-a { color: #4dd; }
.var-b { color: #dd4; }
.var-c { color: #d44; }
.combined { color: #ddd; }
/* text-decoration: underline strikes through the descenders,
   which is ugly and makes it harder to read */
.to-be-combined { border-bottom: 1PX dotted #ddd; }
&lt;/style&gt;

&lt;pre&gt;&lt;tt&gt;&lt;span class="var-a"&gt;a = x₁·y₁&lt;/span&gt;
&lt;span class="var-b"&gt;b = x₁·y₂ + x₂·y₁&lt;/span&gt;
&lt;span class="var-c"&gt;c = x₂·y₂&lt;/span&gt;
&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;We first complicate &lt;tt&gt;b&lt;/tt&gt; by adding &lt;tt&gt;(a-a)&lt;/tt&gt; and &lt;tt&gt;(c-c)&lt;/tt&gt;, then expand:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span class="var-b"&gt;b = x₁·y₂ + x₂·y₁ + &lt;span class="var-a"&gt;(a - a)&lt;/span&gt; + &lt;span class="var-c"&gt;(c - c)&lt;/span&gt;&lt;/span&gt;
&lt;span class="var-b"&gt;b = x₁·y₂ + x₂·y₁ + &lt;span class="var-a"&gt;((x₁·y₁) - (x₁·y₁))&lt;/span&gt; + &lt;span class="var-c"&gt;(x₂·y₂) - (x₂·y₂)&lt;/span&gt;&lt;/span&gt;
&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Next, we remove the parentheses and reorder by moving one &lt;tt&gt;a&lt;/tt&gt; and one &lt;tt&gt;c&lt;/tt&gt; to the left, and finally we can re-group the moved variables:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span class="var-b"&gt;b = x₁·y₂ + x₂·y₁ + &lt;span class="var-a"&gt;x₁·y₁ - x₁·y₁&lt;/span&gt; + &lt;span class="var-c"&gt;x₂·y₂ - x₂·y₂&lt;/span&gt;&lt;/span&gt;
&lt;span class="var-b"&gt;b = &lt;span class="to-be-combined"&gt;&lt;span class="var-a"&gt;x₁·y₁&lt;/span&gt; + &lt;span class="var-c"&gt;x₂·y₂&lt;/span&gt; + x₂·y₁ + x₁·y₂&lt;/span&gt; &lt;span class="var-a"&gt;- x₁·y₁&lt;/span&gt; &lt;span class="var-c"&gt;- x₂·y₂&lt;/span&gt;&lt;/span&gt;
&lt;span class="var-b"&gt;b = &lt;span class="combined"&gt;(x₁ + x₂)·(y₁ + y₂)&lt;/span&gt; &lt;span class="var-a"&gt;- x₁·y₁ &lt;span class="var-c"&gt;- x₂·y₂&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;span class="var-b"&gt;&lt;/span&gt;
&lt;p&gt;And ta-da, as if by magic, we have:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span class="var-b"&gt;b = &lt;span class="combined"&gt;(x₁ + x₂)·(y₁ + y₂)&lt;/span&gt; &lt;span class="var-a"&gt;- a&lt;/span&gt; &lt;span class="var-c"&gt;- c&lt;/span&gt;
&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;span class="var-b"&gt;&lt;/span&gt;
&lt;p&gt;If you compare this with the original definition of &lt;tt&gt;b&lt;/tt&gt;, you'll notice that the new definition has one multiplication instead of two. The multiplication factors are slightly larger than in the original formula, but because there's only one, we end up doing less work.  Of course, we'll still have to do all those additions and subtractions, but with big enough numbers, it's faster than multiplying twice. That's because the complexity of this algorithm has dropped from &lt;tt&gt;O(n²)&lt;/tt&gt; to something less.  The exact complexity turns out to be &lt;tt&gt;O(n^log3)&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Now, this is the &lt;i&gt;asymptotic&lt;/i&gt; complexity.  You can easily tell from the new formula of &lt;tt&gt;b&lt;/tt&gt; that it uses several more operations and it requires splitting up &lt;tt&gt;x&lt;/tt&gt; and &lt;tt&gt;y&lt;/tt&gt; in two parts, which requires allocating memory for them and copying out the parts.  This is a lot of overhead, which means that Karatsuba's algorithm only becomes more efficient than the &amp;quot;school book&amp;quot; algorithm for (very) large numbers. The same is true for the FFT-based algorithms mentioned earlier, those improve performance only for even larger numbers, because they split up the numbers into even more pieces.  This is a (better) reason why it's probably not worth adding the extra code and complexity of an FFT implementation to CHICKEN core.&lt;/p&gt;
&lt;p&gt;In code, a naive implementation of Karatsuba's algorithm is quite simple as well:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="comment"&gt;;; Where this is called, we ensure that |x| &amp;lt;= |y|
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;karatsuba-multiply x y&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let*&lt;/span&gt;&lt;/i&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;rs &lt;span class="paren5"&gt;(&lt;span class="default"&gt;fx* &lt;span class="paren6"&gt;(&lt;span class="default"&gt;signum x&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren6"&gt;(&lt;span class="default"&gt;signum y&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;     &lt;span class="comment"&gt;; Result&amp;#x27;s sign (-1 or +1)
&lt;/span&gt;         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;x &lt;span class="paren5"&gt;(&lt;span class="default"&gt;abs x&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;n &lt;span class="paren5"&gt;(&lt;span class="default"&gt;bignum-digit-count y&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;n/2 &lt;span class="paren5"&gt;(&lt;span class="default"&gt;fxshr n 1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;                    &lt;span class="comment"&gt;; (floor (/ n 2))
&lt;/span&gt;         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;bits &lt;span class="paren5"&gt;(&lt;span class="default"&gt;fx* n/2 &lt;span class="special"&gt;*bignum-digit-bits*&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;x-hi &lt;span class="paren5"&gt;(&lt;span class="default"&gt;extract-digits x n/2 #f&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;     &lt;span class="comment"&gt;; x[n..n/2]
&lt;/span&gt;         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;x-lo &lt;span class="paren5"&gt;(&lt;span class="default"&gt;extract-digits x 0 n/2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;     &lt;span class="comment"&gt;; x[n/2..0]
&lt;/span&gt;    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let*&lt;/span&gt;&lt;/i&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;y &lt;span class="paren6"&gt;(&lt;span class="default"&gt;abs y&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
           &lt;span class="paren5"&gt;(&lt;span class="default"&gt;y-hi &lt;span class="paren6"&gt;(&lt;span class="default"&gt;extract-digits y n/2 #f&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;   &lt;span class="comment"&gt;; y[n..n/2]
&lt;/span&gt;           &lt;span class="paren5"&gt;(&lt;span class="default"&gt;y-lo &lt;span class="paren6"&gt;(&lt;span class="default"&gt;extract-digits y 0 n/2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;    &lt;span class="comment"&gt;; y[n/2..0]
&lt;/span&gt;           &lt;span class="paren5"&gt;(&lt;span class="default"&gt;a  &lt;span class="paren6"&gt;(&lt;span class="default"&gt;* x-hi y-hi&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
           &lt;span class="paren5"&gt;(&lt;span class="default"&gt;b  &lt;span class="paren6"&gt;(&lt;span class="default"&gt;* x-lo y-lo&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
           &lt;span class="paren5"&gt;(&lt;span class="default"&gt;c  &lt;span class="paren6"&gt;(&lt;span class="default"&gt;* &lt;span class="paren1"&gt;(&lt;span class="default"&gt;- x-hi x-lo&lt;/span&gt;)&lt;/span&gt;
                  &lt;span class="paren1"&gt;(&lt;span class="default"&gt;- y-hi y-lo&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;* rs &lt;span class="paren5"&gt;(&lt;span class="default"&gt;+ &lt;span class="paren6"&gt;(&lt;span class="default"&gt;arithmetic-shift a &lt;span class="paren1"&gt;(&lt;span class="default"&gt;fx* bits 2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
               &lt;span class="paren6"&gt;(&lt;span class="default"&gt;+ &lt;span class="paren1"&gt;(&lt;span class="default"&gt;arithmetic-shift &lt;span class="paren2"&gt;(&lt;span class="default"&gt;+ b &lt;span class="paren3"&gt;(&lt;span class="default"&gt;- a c&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; bits&lt;/span&gt;)&lt;/span&gt;
                   b&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;)&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Especially helpful here is that the operators prefixed by &lt;tt&gt;fx&lt;/tt&gt; indicate clearly when we're working with fixnums.  This uses absolute numbers because that's simpler to deal with, especially when using &lt;tt&gt;extract-digits&lt;/tt&gt; to quickly get a range of bignum digits.  It might be possible to make this faster by operating directly on the signed numbers.&lt;/p&gt;
&lt;p&gt;In CHICKEN 5, this algorithm has been translated to C for stupid reasons which I will explain in a later post.  But this Scheme code is taken directly from the numbers egg and cleaned up only slightly.&lt;/p&gt;
&lt;p&gt;According to &lt;a href="https://members.loria.fr/PZimmermann/mca/pub226.html" class="external"&gt;MCA&lt;/a&gt;, an optimal implementation should avoid allocating the intermediate calculations of &lt;tt&gt;(- x-hi x-lo)&lt;/tt&gt; and &lt;tt&gt;(- y-hi y-lo)&lt;/tt&gt;.  In a low level C-based implementation like CHICKEN 5's, it might be easier to perform in-place modification of these numbers, but so far I haven't been successful in doing this.  Nevertheless, our Karatsuba implementation is efficient enough for now.&lt;/p&gt;
&lt;p&gt;Sometimes, the Karatsuba algorithm is referred to as the &lt;i&gt;Toom-Cook&lt;/i&gt; algorithm.  That's because &lt;a href="https://en.wikipedia.org/wiki/Toom-Cook" class="external"&gt;Toom and Cook&lt;/a&gt; figured out a way to generalise the algorithm.  This way, you can split the numbers into any number of components, instead of two components like Karatsuba did.  Apparently there's a sweet spot in number sizes where a 3-way split is faster than a 2-way split, but pretty soon after that, the numbers get big enough and the FFT-based algorithms overtake Toom-Cook in efficiency.&lt;/p&gt;&lt;a href="#faster-division"&gt;
&lt;h2 id="faster-division"&gt;Faster division&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Faster multiplication is interesting, but division is the real tortoise in this race, so let's see how we can speed that up.  It turns out that the approaches are rather similar to those of multiplication.&lt;/p&gt;&lt;a href="#division-by-a-fixnum"&gt;
&lt;h3 id="division-by-a-fixnum"&gt;Division by a fixnum&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Recall that the division algorithm needs to &amp;quot;guess&amp;quot; how many times the denominator fits in the numerator based on the first half-digit (plus some magic surrounding the second half-digit).  If the denominator is itself is only a half-digit, there's no need to guess.&lt;/p&gt;
&lt;p&gt;So, just like when multiplying by a small fixnum, we have a destructive division algorithm that operates on a copy of the numerator.  The Scheme48 version I started with:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="comment"&gt;/* Given (denominator &amp;gt; 1), it is fairly easy to show that
   (quotient_high &amp;lt; BIGNUM_RADIX_ROOT), after which it is easy to see
   that all digits are &amp;lt; BIGNUM_RADIX. */&lt;/span&gt;

&lt;span class="symbol"&gt;static&lt;/span&gt; bignum_digit_type
bignum_destructive_scale_down&lt;span class="paren1"&gt;(&lt;span class="default"&gt;bignum_type bignum, bignum_digit_type denominator&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  bignum_digit_type numerator;
  bignum_digit_type remainder = 0;
  bignum_digit_type two_digits;
&lt;span class="special"&gt;#define quotient_high remainder
&lt;/span&gt;  bignum_digit_type * start = &lt;span class="paren2"&gt;(&lt;span class="default"&gt;BIGNUM_START_PTR &lt;span class="paren3"&gt;(&lt;span class="default"&gt;bignum&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
  bignum_digit_type * scan = &lt;span class="paren2"&gt;(&lt;span class="default"&gt;start + &lt;span class="paren3"&gt;(&lt;span class="default"&gt;BIGNUM_LENGTH &lt;span class="paren4"&gt;(&lt;span class="default"&gt;bignum&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
  BIGNUM_ASSERT &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;denominator &amp;gt; 1&lt;/span&gt;)&lt;/span&gt; &amp;amp;&amp;amp; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;denominator &amp;lt; BIGNUM_RADIX_ROOT&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
  &lt;span class="symbol"&gt;while&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;start &amp;lt; scan&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
      two_digits = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;*--scan&lt;/span&gt;)&lt;/span&gt;;
      numerator = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;HD_CONS &lt;span class="paren4"&gt;(&lt;span class="default"&gt;remainder, &lt;span class="paren5"&gt;(&lt;span class="default"&gt;HD_HIGH &lt;span class="paren6"&gt;(&lt;span class="default"&gt;two_digits&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
      quotient_high = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;numerator / denominator&lt;/span&gt;)&lt;/span&gt;;
      numerator = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;HD_CONS &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;numerator % denominator&lt;/span&gt;)&lt;/span&gt;, &lt;span class="paren5"&gt;(&lt;span class="default"&gt;HD_LOW &lt;span class="paren6"&gt;(&lt;span class="default"&gt;two_digits&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
      &lt;span class="paren3"&gt;(&lt;span class="default"&gt;*scan&lt;/span&gt;)&lt;/span&gt; = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;HD_CONS &lt;span class="paren4"&gt;(&lt;span class="default"&gt;quotient_high, &lt;span class="paren5"&gt;(&lt;span class="default"&gt;numerator / denominator&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
      remainder = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;numerator % denominator&lt;/span&gt;)&lt;/span&gt;;
    &lt;/span&gt;}&lt;/span&gt;
  &lt;span class="symbol"&gt;return&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;remainder&lt;/span&gt;)&lt;/span&gt;;
&lt;span class="special"&gt;#undef quotient_high
&lt;/span&gt;&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;And the smaller version based, again, on the division algorithm from &lt;a href="http://www.hackersdelight.org/" class="external"&gt;Hacker's Delight&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="symbol"&gt;static&lt;/span&gt; C_uword bignum_digits_destructive_scale_down&lt;span class="paren1"&gt;(&lt;span class="default"&gt;
  C_uword *start, C_uword *end, C_uword denominator&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  C_uword digit, k = 0;
  C_uhword q_j_hi, q_j_lo;

  &lt;span class="comment"&gt;/* Single digit divisor case from Hacker&amp;#x27;s Delight, Figure 9-1,
   * adapted to modify u[] in-place instead of writing to q[].
   */&lt;/span&gt;
  &lt;span class="symbol"&gt;while&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;start &amp;lt; end&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    digit = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;*--end&lt;/span&gt;)&lt;/span&gt;;

    k = C_BIGNUM_DIGIT_COMBINE&lt;span class="paren3"&gt;(&lt;span class="default"&gt;k, C_BIGNUM_DIGIT_HI_HALF&lt;span class="paren4"&gt;(&lt;span class="default"&gt;digit&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* j */&lt;/span&gt;
    q_j_hi = k / denominator;
    k -= q_j_hi * denominator;

    k = C_BIGNUM_DIGIT_COMBINE&lt;span class="paren3"&gt;(&lt;span class="default"&gt;k, C_BIGNUM_DIGIT_LO_HALF&lt;span class="paren4"&gt;(&lt;span class="default"&gt;digit&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* j-1 */&lt;/span&gt;
    q_j_lo = k / denominator;
    k -= q_j_lo * denominator;
    
    *end = C_BIGNUM_DIGIT_COMBINE&lt;span class="paren3"&gt;(&lt;span class="default"&gt;q_j_hi, q_j_lo&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt;
  &lt;span class="symbol"&gt;return&lt;/span&gt; k; &lt;span class="comment"&gt;/* The remainder */&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;And, just like with multiplication, if you're dividing by a power of two, there's an easy optimisation: you can simply shift the numerator right by as many bits as the 2log of the denominator.  The remainder is formed by the bits that were shifted out.&lt;/p&gt;&lt;a href="#burnikel-ziegler-division"&gt;
&lt;h3 id="burnikel-ziegler-division"&gt;Burnikel-Ziegler division&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;And here too, there's a divide and conquer algorithm named after the mathematician (or, in this case, mathematicians) who discovered it. This algorithm is a &lt;i&gt;lot&lt;/i&gt; more complicated than Karatsuba's relatively simple algebraic trick, and a lot harder to implement correctly.  The &lt;a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.47.565&amp;amp;rep=rep1&amp;amp;type=pdf" class="external"&gt;paper&lt;/a&gt; is long and still not very helpful when it comes down to the crucial details.  I found the super-elegant presentation in &lt;a href="https://members.loria.fr/PZimmermann/mca/pub226.html" class="external"&gt;MCA&lt;/a&gt; to be more helpful in figuring out details.  Especially the algorithm's start-up procedure is tricky to get right.  I will use the explanation style from MCA because it is simpler than the original paper.&lt;/p&gt;
&lt;p&gt;The algorithm is similar to the classical &amp;quot;school book&amp;quot; division algorithm, but &amp;quot;in the large&amp;quot;.  The basic idea is that we operate on partial bignums at a time instead of on half-digits.  The core algorithm handles only &lt;tt&gt;2n/n&lt;/tt&gt; division.  This means that the numerator &lt;i&gt;must&lt;/i&gt; be twice the size of the denominator.  It splits the numerator in two halves.  Each half is then divided by the entire denominator and finally recombined to form the result.  These two divisions are themselves also done in two steps, thereby making the numbers smaller in the recursion.&lt;/p&gt;
&lt;p&gt;Because the intermediate division only divides by the first half of the denominator, the result may end up negative.  So, like the schoolbook method, this algorithm also makes an adjustment when re-joining the two intermediate results.  The core algorithm is as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the denominator is smaller than some limit, fall back to &amp;quot;primary school&amp;quot; algorithm, otherwise:&lt;/li&gt;
&lt;li&gt;Split the denominator &lt;tt&gt;B&lt;/tt&gt; in two: &lt;tt&gt;B₁·β + B₂&lt;/tt&gt;.  So, if &lt;tt&gt;B&lt;/tt&gt; is a bignum of &lt;tt&gt;n&lt;/tt&gt; limbs, the base &lt;tt&gt; β&lt;/tt&gt; is half that.&lt;/li&gt;
&lt;li&gt;Next, split the numerator &lt;tt&gt;A&lt;/tt&gt; into four such parts: &lt;tt&gt;A₁·β³ + A₂·β² + A₃·β + A₄&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;First half:
&lt;ul&gt;
&lt;li&gt;Divide &lt;tt&gt;A₁·β + A₂&lt;/tt&gt; by &lt;tt&gt;B₁&lt;/tt&gt;, yielding the &lt;i&gt;guessed&lt;/i&gt; quotient &lt;tt&gt;Q̂₁&lt;/tt&gt; and remainder &lt;tt&gt;R₁&lt;/tt&gt; (the recursive step).&lt;/li&gt;
&lt;li&gt;Combine the remainder &lt;tt&gt;R₁&lt;/tt&gt; with &lt;tt&gt;A₃&lt;/tt&gt; and subtract &lt;tt&gt;Q̂·B₂&lt;/tt&gt;, yielding &lt;tt&gt;R̂₁ = R₁·β + A₃ - Q̂·B₂&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;While &lt;tt&gt;R̂₁ &amp;lt; Q̂₁·B₂&lt;/tt&gt;, adjust the guess; &lt;tt&gt;Q̂₁:=Q̂₁-1&lt;/tt&gt; and &lt;tt&gt;R̂₁:=R̂₁+B&lt;/tt&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Second half:
&lt;ul&gt;
&lt;li&gt;Divide &lt;tt&gt;R̂₁&lt;/tt&gt; by &lt;tt&gt;B₁&lt;/tt&gt;, yielding the &lt;i&gt;guessed&lt;/i&gt; quotient &lt;tt&gt;Q̂₂&lt;/tt&gt; and remainder &lt;tt&gt;R&lt;/tt&gt; (another recursive step).&lt;/li&gt;
&lt;li&gt;Combine the remainder &lt;tt&gt;R&lt;/tt&gt; with &lt;tt&gt;A₄&lt;/tt&gt; and subtract &lt;tt&gt;Q̂·B₂&lt;/tt&gt;, yielding &lt;tt&gt;R̂ = R + A₄ - Q̂·B₂&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;While &lt;tt&gt;R̂ &amp;lt; Q̂₂·B₂&lt;/tt&gt;, adjust the guess; &lt;tt&gt;Q̂₂:=Q̂₂-1&lt;/tt&gt; and &lt;tt&gt;R̂:=R̂+B&lt;/tt&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Recombination of quotient after division:
&lt;ul&gt;
&lt;li&gt;The final quotient is &lt;tt&gt;Q̂₁·β + Q̂₂&lt;/tt&gt;, the final remainder is just &lt;tt&gt;R̂&lt;/tt&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;The interesting part is that &lt;tt&gt;B₂&lt;/tt&gt; is only ever used for checking the guess.  It is not involved in any division.  Of course, in the recursion &lt;tt&gt;B₂&lt;/tt&gt; is also split in two parts, so the high half will be used in the next division, and so on.&lt;/p&gt;
&lt;p&gt;In the diagram you can see how it works on a (very) small sample:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/burnikel-2div1.svg" /&gt;&lt;/p&gt;
&lt;p&gt;In the diagram, &lt;tt&gt;B₁ = 31&lt;/tt&gt; is shown in white on the left in the first and fourth rows. &lt;tt&gt;B₂ = 21&lt;/tt&gt; is shown in green on the left in the second and final rows.  In the first row you also see highlighted in white &lt;tt&gt;A₁·β + A₂ = 3456&lt;/tt&gt; and &lt;tt&gt;R₁ = 15&lt;/tt&gt;.  In the second row, &lt;tt&gt;A₃ = 78&lt;/tt&gt; is shown in white, as it drops down to form &lt;tt&gt;R̂₁ = R₁·β + A₃ = 1578&lt;/tt&gt; with &lt;tt&gt;Q̂₁ = 111&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Between the second and third rows, &lt;tt&gt;Q̂₁ = 110&lt;/tt&gt; is adjusted to &lt;tt&gt;111&lt;/tt&gt; and &lt;tt&gt;R̂₁ = -753&lt;/tt&gt; is adjusted to &lt;tt&gt;2368&lt;/tt&gt; by adding the numerator.&lt;/p&gt;
&lt;p&gt;In the third row we continue with the second half, dividing &lt;tt&gt;R̂₁&lt;/tt&gt; by &lt;tt&gt;B₁&lt;/tt&gt; in the same manner and then recombining &lt;tt&gt;R = 43&lt;/tt&gt; with &lt;tt&gt;A₄ = 67&lt;/tt&gt; and subtracting &lt;tt&gt;Q̂·B₂ = 1575&lt;/tt&gt;.  As no more adjustments are needed, we're done, with &lt;tt&gt;R̂ = 2792&lt;/tt&gt; and &lt;tt&gt;Q̂₂ = 75&lt;/tt&gt;.  Combine &lt;tt&gt;Q̂₁,Q̂₂&lt;/tt&gt; into &lt;tt&gt;Q = 11075&lt;/tt&gt; and we're done!&lt;/p&gt;
&lt;p&gt;Burnikel and Ziegler present the algorithm in their paper in a bit of a roundabout way that didn't make sense to me at first.  It requires understanding the big picture, which they don't really explain up front.  So it's best to read the paper entirely, and then go back and re-read it to grasp the details.  It's a bit bottom-up in a sense, because they refactor it into two algorithms; one for dividing numbers &lt;tt&gt;2n/n&lt;/tt&gt;, and one for dividing numbers &lt;tt&gt;3n/2n&lt;/tt&gt;.  This confused me no end, as it resulted in a bit of a cyclic definition.&lt;/p&gt;
&lt;p&gt;In the explanation I gave above, &lt;tt&gt;2n/n&lt;/tt&gt; is the overall algorithm as a whole.  The first and second &amp;quot;halves&amp;quot; of the algorithm are really identical, and represented by Burnikel and Ziegler as two calls to the &lt;tt&gt;3n/2n&lt;/tt&gt; algorithm.  This can be seen in the Scheme code below:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;digit-bits n&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;fx* &lt;span class="special"&gt;*bignum-digit-bits*&lt;/span&gt; n&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;    &lt;span class="comment"&gt;; Small helper
&lt;/span&gt;
&lt;span class="comment"&gt;;; Here and in 2n/1n we pass both b and [b1, b2] to avoid splitting
&lt;/span&gt;&lt;span class="comment"&gt;;; up the number more than once.  This is a helper function for 2n/n.
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;burnikel-ziegler-3n/2n a12 a3 b b1 b2 n&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;receive &lt;span class="paren3"&gt;(&lt;span class="default"&gt;q^ r1&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;if&lt;/span&gt;&lt;/i&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&amp;lt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;arithmetic-shift a12 &lt;span class="paren6"&gt;(&lt;span class="default"&gt;fxneg &lt;span class="paren1"&gt;(&lt;span class="default"&gt;digit-bits n&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; b1&lt;/span&gt;)&lt;/span&gt;
          &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let*&lt;/span&gt;&lt;/i&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;span class="paren6"&gt;(&lt;span class="default"&gt;n/2 &lt;span class="paren1"&gt;(&lt;span class="default"&gt;fxshr n 1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;                     &lt;span class="comment"&gt;; (floor (/ n 2))
&lt;/span&gt;                 &lt;span class="paren6"&gt;(&lt;span class="default"&gt;b11 &lt;span class="paren1"&gt;(&lt;span class="default"&gt;extract-digits b1 n/2 #f&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;      &lt;span class="comment"&gt;; b1[n..n/2]
&lt;/span&gt;                 &lt;span class="paren6"&gt;(&lt;span class="default"&gt;b12 &lt;span class="paren1"&gt;(&lt;span class="default"&gt;extract-digits b1 0 n/2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;      &lt;span class="comment"&gt;; b1[n/2..0]
&lt;/span&gt;            &lt;span class="paren5"&gt;(&lt;span class="default"&gt;burnikel-ziegler-2n/1n a12 b1 b11 b12 n&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
          &lt;span class="comment"&gt;;; Don&amp;#x27;t bother dividing if a1 is a larger number than b1.
&lt;/span&gt;	  &lt;span class="comment"&gt;;; We use a maximum guess instead (see paper for proof).
&lt;/span&gt;          &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;span class="paren6"&gt;(&lt;span class="default"&gt;base*n &lt;span class="paren1"&gt;(&lt;span class="default"&gt;digit-bits n&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
            &lt;span class="paren5"&gt;(&lt;span class="default"&gt;values &lt;span class="paren6"&gt;(&lt;span class="default"&gt;- &lt;span class="paren1"&gt;(&lt;span class="default"&gt;arithmetic-shift 1 base*n&lt;/span&gt;)&lt;/span&gt; 1&lt;/span&gt;)&lt;/span&gt;  &lt;span class="comment"&gt;; B^n-1
&lt;/span&gt;                    &lt;span class="paren6"&gt;(&lt;span class="default"&gt;+ &lt;span class="paren1"&gt;(&lt;span class="default"&gt;- a12 &lt;span class="paren2"&gt;(&lt;span class="default"&gt;arithmetic-shift b1 base*n&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; b1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;r1a3 &lt;span class="paren6"&gt;(&lt;span class="default"&gt;+ &lt;span class="paren1"&gt;(&lt;span class="default"&gt;arithmetic-shift r1 &lt;span class="paren2"&gt;(&lt;span class="default"&gt;digit-bits n&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; a3&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; lp &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;span class="paren6"&gt;(&lt;span class="default"&gt;r^ &lt;span class="paren1"&gt;(&lt;span class="default"&gt;- r1a3 &lt;span class="paren2"&gt;(&lt;span class="default"&gt;* q^ b2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
               &lt;span class="paren6"&gt;(&lt;span class="default"&gt;q^ q^&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
        &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;if&lt;/span&gt;&lt;/i&gt; &lt;span class="paren6"&gt;(&lt;span class="default"&gt;negative? r^&lt;/span&gt;)&lt;/span&gt;
            &lt;span class="paren6"&gt;(&lt;span class="default"&gt;lp &lt;span class="paren1"&gt;(&lt;span class="default"&gt;+ r^ b&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;- q^ 1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;                     &lt;span class="comment"&gt;; Adjust!
&lt;/span&gt;            &lt;span class="paren6"&gt;(&lt;span class="default"&gt;values q^ r^&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="comment"&gt;;; The main 2n/n algorithm which calls 3n/2n twice.  Here, a is the
&lt;/span&gt;&lt;span class="comment"&gt;;; numerator, b the denominator, n is the length of b (in digits) and
&lt;/span&gt;&lt;span class="comment"&gt;;; b1 and b2 are the two halves of b (these never change).
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;burnikel-ziegler-2n/1n a b b1 b2 n&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;if&lt;/span&gt;&lt;/i&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;or &lt;span class="paren4"&gt;(&lt;span class="default"&gt;fxodd? n&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;fx&amp;lt; n DIV-LIMIT&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;                &lt;span class="comment"&gt;; Can&amp;#x27;t recurse?
&lt;/span&gt;      &lt;span class="paren3"&gt;(&lt;span class="default"&gt;quotient&amp;amp;remainder a b&lt;/span&gt;)&lt;/span&gt;                         &lt;span class="comment"&gt;; Use school division
&lt;/span&gt;      &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let*&lt;/span&gt;&lt;/i&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;n/2 &lt;span class="paren6"&gt;(&lt;span class="default"&gt;fxshr n 1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
             &lt;span class="comment"&gt;;; Split a and b into n-sized parts [a1, ..., a4] and [b1, b2]
&lt;/span&gt;             &lt;span class="paren5"&gt;(&lt;span class="default"&gt;a12 &lt;span class="paren6"&gt;(&lt;span class="default"&gt;extract-digits a n #f&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;             &lt;span class="comment"&gt;; a[m..n]
&lt;/span&gt;             &lt;span class="paren5"&gt;(&lt;span class="default"&gt;a3  &lt;span class="paren6"&gt;(&lt;span class="default"&gt;extract-digits a n/2 n&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;            &lt;span class="comment"&gt;; a[n..n/2]
&lt;/span&gt;             &lt;span class="paren5"&gt;(&lt;span class="default"&gt;a4  &lt;span class="paren6"&gt;(&lt;span class="default"&gt;extract-digits a 0 n/2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;           &lt;span class="comment"&gt;; a[n..0]
&lt;/span&gt;        &lt;span class="comment"&gt;;; Calculate high quotient and intermediate remainder (first half)
&lt;/span&gt;        &lt;span class="paren4"&gt;(&lt;span class="default"&gt;receive &lt;span class="paren5"&gt;(&lt;span class="default"&gt;q1 r1&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;burnikel-ziegler-3n/2n a12 a3 b b1 b2 n/2&lt;/span&gt;)&lt;/span&gt;
          &lt;span class="comment"&gt;;; Calculate low quotient and final remainder (second half)
&lt;/span&gt;          &lt;span class="paren5"&gt;(&lt;span class="default"&gt;receive &lt;span class="paren6"&gt;(&lt;span class="default"&gt;q2 r&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren6"&gt;(&lt;span class="default"&gt;burnikel-ziegler-3n/2n r1 a4 b b1 b2 n/2&lt;/span&gt;)&lt;/span&gt;
            &lt;span class="comment"&gt;;; Recombine quotient parts as q = [q1,q2]
&lt;/span&gt;            &lt;span class="paren6"&gt;(&lt;span class="default"&gt;values &lt;span class="paren1"&gt;(&lt;span class="default"&gt;+ &lt;span class="paren2"&gt;(&lt;span class="default"&gt;arithmetic-shift q1 &lt;span class="paren3"&gt;(&lt;span class="default"&gt;digit-bits n/2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; q2&lt;/span&gt;)&lt;/span&gt; r&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The reason &lt;tt&gt;b1, b2&lt;/tt&gt; are passed in but not &lt;tt&gt;a1, ..., a4&lt;/tt&gt; has to do with the &amp;quot;full&amp;quot; algorithm, which deals with unbalanced division where &lt;tt&gt;a&lt;/tt&gt; may be bigger than &lt;tt&gt;2n&lt;/tt&gt;, given &lt;tt&gt;b&lt;/tt&gt; of size &lt;tt&gt;n&lt;/tt&gt;.  There, &lt;tt&gt;b&lt;/tt&gt; is constant, so it pays off to &amp;quot;cache&amp;quot; &lt;tt&gt;b1&lt;/tt&gt; and &lt;tt&gt;b2&lt;/tt&gt;. Because &lt;tt&gt;a&lt;/tt&gt; keeps changing, we don't cache it.&lt;/p&gt;
&lt;p&gt;This full algorithm for dividing two numbers &lt;tt&gt;x&lt;/tt&gt; and &lt;tt&gt;y&lt;/tt&gt; of arbitrary lengths is as follows: If the denominator &lt;tt&gt;y&lt;/tt&gt; is of size &lt;tt&gt;n&lt;/tt&gt;, we can simply chop up the numerator &lt;tt&gt;x&lt;/tt&gt; into &lt;tt&gt;n&lt;/tt&gt;-sized pieces.  We then perform a division algorithm on those pieces, using a sort of &amp;quot;sliding window&amp;quot; over &lt;tt&gt;x&lt;/tt&gt;.  This passes &lt;tt&gt;[x_{i+1},x_i]&lt;/tt&gt; and &lt;tt&gt;y&lt;/tt&gt; to &lt;tt&gt;2n/n&lt;/tt&gt;, and recombines the remainder &lt;tt&gt;r_i&lt;/tt&gt; with &lt;tt&gt;x_{i-1} &lt;/tt&gt; to get &lt;tt&gt;[r_i,x_{i-1}]&lt;/tt&gt;, which is used for &lt;tt&gt;2n/n&lt;/tt&gt; in the next iteration, and so on.&lt;/p&gt;
&lt;p&gt;Well, in theory it's simple...&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;quotient&amp;amp;remainder/burnikel-ziegler x y return-quot? return-rem?&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="comment"&gt;;; The caller will already have verified that abs(x) &amp;gt; abs(y), but we
&lt;/span&gt;  &lt;span class="comment"&gt;;; need to remember the signs of the input and make them absolute.
&lt;/span&gt;  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let*&lt;/span&gt;&lt;/i&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;q-neg? &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;if&lt;/span&gt;&lt;/i&gt; &lt;span class="paren6"&gt;(&lt;span class="default"&gt;negative? y&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren6"&gt;(&lt;span class="default"&gt;not &lt;span class="paren1"&gt;(&lt;span class="default"&gt;negative? x&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren6"&gt;(&lt;span class="default"&gt;negative? x&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;r-neg? &lt;span class="paren5"&gt;(&lt;span class="default"&gt;negative? x&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;x &lt;span class="paren5"&gt;(&lt;span class="default"&gt;abs x&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;y &lt;span class="paren5"&gt;(&lt;span class="default"&gt;abs y&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;s &lt;span class="paren5"&gt;(&lt;span class="default"&gt;bignum-digit-count y&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="comment"&gt;;; Define m as min{2^k|(2^k)*DIV_LIMIT &amp;gt; s}.
&lt;/span&gt;         &lt;span class="comment"&gt;;; This ensures we shift as little as possible (less pressure
&lt;/span&gt;         &lt;span class="comment"&gt;;; on the GC) while maintaining a power of two until we drop
&lt;/span&gt;         &lt;span class="comment"&gt;;; below the threshold, so we can always split N in half.
&lt;/span&gt;         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;m &lt;span class="paren5"&gt;(&lt;span class="default"&gt;fx* 2 &lt;span class="paren6"&gt;(&lt;span class="default"&gt;integer-length &lt;span class="paren1"&gt;(&lt;span class="default"&gt;fx/ s DIV-LIMIT&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;j &lt;span class="paren5"&gt;(&lt;span class="default"&gt;fx/ &lt;span class="paren6"&gt;(&lt;span class="default"&gt;fx+ s &lt;span class="paren1"&gt;(&lt;span class="default"&gt;fx- m 1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; m&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;  &lt;span class="comment"&gt;; j = s/m, rounded up
&lt;/span&gt;         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;n &lt;span class="paren5"&gt;(&lt;span class="default"&gt;fx* j m&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="comment"&gt;;; Normalisation, just like with normal school division
&lt;/span&gt;         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;norm-shift &lt;span class="paren5"&gt;(&lt;span class="default"&gt;fx- &lt;span class="paren6"&gt;(&lt;span class="default"&gt;digit-bits n&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren6"&gt;(&lt;span class="default"&gt;integer-length y&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;x &lt;span class="paren5"&gt;(&lt;span class="default"&gt;arithmetic-shift x norm-shift&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;y &lt;span class="paren5"&gt;(&lt;span class="default"&gt;arithmetic-shift y norm-shift&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="comment"&gt;;; l needs to be the smallest value so that a &amp;lt; base^{l*n}/2
&lt;/span&gt;         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;l &lt;span class="paren5"&gt;(&lt;span class="default"&gt;fx/ &lt;span class="paren6"&gt;(&lt;span class="default"&gt;fx+ &lt;span class="paren1"&gt;(&lt;span class="default"&gt;bignum-digit-count x&lt;/span&gt;)&lt;/span&gt; n&lt;/span&gt;)&lt;/span&gt; n&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;l &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;if&lt;/span&gt;&lt;/i&gt; &lt;span class="paren6"&gt;(&lt;span class="default"&gt;fx= &lt;span class="paren1"&gt;(&lt;span class="default"&gt;digit-bits l&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;integer-length x&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren6"&gt;(&lt;span class="default"&gt;fx+ l 1&lt;/span&gt;)&lt;/span&gt; l&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;t &lt;span class="paren5"&gt;(&lt;span class="default"&gt;fxmax l 2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;y-hi &lt;span class="paren5"&gt;(&lt;span class="default"&gt;extract-digits y &lt;span class="paren6"&gt;(&lt;span class="default"&gt;fxshr n 1&lt;/span&gt;)&lt;/span&gt; #f&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;   &lt;span class="comment"&gt;; y[n..n/2]
&lt;/span&gt;         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;y-lo &lt;span class="paren5"&gt;(&lt;span class="default"&gt;extract-digits y 0 &lt;span class="paren6"&gt;(&lt;span class="default"&gt;fxshr n 1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;   &lt;span class="comment"&gt;; y[n/2..0]
&lt;/span&gt;    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; lp &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;zi &lt;span class="paren6"&gt;(&lt;span class="default"&gt;arithmetic-shift x &lt;span class="paren1"&gt;(&lt;span class="default"&gt;fxneg &lt;span class="paren2"&gt;(&lt;span class="default"&gt;digit-bits &lt;span class="paren3"&gt;(&lt;span class="default"&gt;fx* &lt;span class="paren4"&gt;(&lt;span class="default"&gt;fx- t 2&lt;/span&gt;)&lt;/span&gt; n&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
             &lt;span class="paren5"&gt;(&lt;span class="default"&gt;i &lt;span class="paren6"&gt;(&lt;span class="default"&gt;fx- t 2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
             &lt;span class="paren5"&gt;(&lt;span class="default"&gt;quot 0&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;receive &lt;span class="paren5"&gt;(&lt;span class="default"&gt;qi ri&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;burnikel-ziegler-2n/1n zi y y-hi y-lo n&lt;/span&gt;)&lt;/span&gt;
        &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; &lt;span class="paren6"&gt;(&lt;span class="default"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;quot &lt;span class="paren2"&gt;(&lt;span class="default"&gt;+ &lt;span class="paren3"&gt;(&lt;span class="default"&gt;arithmetic-shift quot &lt;span class="paren4"&gt;(&lt;span class="default"&gt;digit-bits n&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; qi&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
          &lt;span class="paren6"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;if&lt;/span&gt;&lt;/i&gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;fx&amp;gt; i 0&lt;/span&gt;)&lt;/span&gt;
              &lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;zi-1 &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let*&lt;/span&gt;&lt;/i&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;span class="paren6"&gt;(&lt;span class="default"&gt;base*n*i-1 &lt;span class="paren1"&gt;(&lt;span class="default"&gt;fx* n &lt;span class="paren2"&gt;(&lt;span class="default"&gt;fx- i 1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                                 &lt;span class="paren6"&gt;(&lt;span class="default"&gt;base*n*i   &lt;span class="paren1"&gt;(&lt;span class="default"&gt;fx* n i&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                                 &lt;span class="comment"&gt;;; x_{i-1} = x[n*i..n*(i-1)]
&lt;/span&gt;                                 &lt;span class="paren6"&gt;(&lt;span class="default"&gt;xi-1 &lt;span class="paren1"&gt;(&lt;span class="default"&gt;extract-digits x base*n*i-1 base*n*i&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                            &lt;span class="paren5"&gt;(&lt;span class="default"&gt;+ &lt;span class="paren6"&gt;(&lt;span class="default"&gt;arithmetic-shift ri &lt;span class="paren1"&gt;(&lt;span class="default"&gt;digit-bits n&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; xi-1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                &lt;span class="paren2"&gt;(&lt;span class="default"&gt;lp zi-1 &lt;span class="paren3"&gt;(&lt;span class="default"&gt;fx- i 1&lt;/span&gt;)&lt;/span&gt; quot&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
              &lt;span class="comment"&gt;;; De-normalise remainder, but only if necessary
&lt;/span&gt;              &lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;rem &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;if&lt;/span&gt;&lt;/i&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;or &lt;span class="paren6"&gt;(&lt;span class="default"&gt;not return-rem?&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren6"&gt;(&lt;span class="default"&gt;eq? 0 norm-shift&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                             ri
                             &lt;span class="paren5"&gt;(&lt;span class="default"&gt;arithmetic-shift ri &lt;span class="paren6"&gt;(&lt;span class="default"&gt;fxneg norm-shift&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                &lt;span class="comment"&gt;;; Return values (quot, rem or both) with correct sign:
&lt;/span&gt;                &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;cond&lt;/span&gt;&lt;/i&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;and return-quot? return-rem?&lt;/span&gt;)&lt;/span&gt;
                       &lt;span class="paren4"&gt;(&lt;span class="default"&gt;values &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;if&lt;/span&gt;&lt;/i&gt; q-neg? &lt;span class="paren6"&gt;(&lt;span class="default"&gt;- quot&lt;/span&gt;)&lt;/span&gt; quot&lt;/span&gt;)&lt;/span&gt;
                               &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;if&lt;/span&gt;&lt;/i&gt; r-neg? &lt;span class="paren6"&gt;(&lt;span class="default"&gt;- rem&lt;/span&gt;)&lt;/span&gt; rem&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                      &lt;span class="paren3"&gt;(&lt;span class="default"&gt;return-quot? &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;if&lt;/span&gt;&lt;/i&gt; q-neg? &lt;span class="paren5"&gt;(&lt;span class="default"&gt;- quot&lt;/span&gt;)&lt;/span&gt; quot&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                      &lt;span class="paren3"&gt;(&lt;span class="default"&gt;else &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;if&lt;/span&gt;&lt;/i&gt; r-neg? &lt;span class="paren5"&gt;(&lt;span class="default"&gt;- rem&lt;/span&gt;)&lt;/span&gt; rem&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, this procedure is extremely hairy.  The trickery is in how the bignums are chopped up into &lt;tt&gt;n&lt;/tt&gt;-sized pieces.  The sizes we use should be nice powers of two, which improves the algorithm's effectiveness.  Notice the &lt;tt&gt;(or (fxodd? n) (fx&amp;lt; n DIV-LIMIT))&lt;/tt&gt; check in &lt;tt&gt;2n/1n&lt;/tt&gt;; whenever that is true, we fall back to the school division.  This has to be avoided as much as possible, so that's why we try to scale up the number &lt;tt&gt;x&lt;/tt&gt; to nicely rounded multiples of &lt;tt&gt;n&lt;/tt&gt;.  At the same time, you have to make sure that the numbers don't grow &lt;i&gt;too&lt;/i&gt; large, because that would create &lt;i&gt;more&lt;/i&gt; work for the algorithm!&lt;/p&gt;
&lt;p&gt;The particular calculation is tricky, but the idea is simple: you want to scale up both numbers to the closest power of two that's larger than the cutoff size.  Then, the numerator is scaled up so that it is a size that's a multiple of &lt;tt&gt;n&lt;/tt&gt;, the final size of the denominator. No doubt my implementation of this part of the algorithm can be simplified.&lt;/p&gt;&lt;a href="#reading-list"&gt;
&lt;h2 id="reading-list"&gt;Reading list&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;First, start with the reading list of the &lt;a href="/posts/numeric-tower-part-2.html" class="internal"&gt;previous post&lt;/a&gt;, because most of those references discuss advanced algorithms as well.  The ones below are either more specific or more advanced than the descriptions you'll find in the standard references.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The GMP manual has a &lt;a href="https://gmplib.org/manual/Karatsuba-Multiplication.html#Karatsuba-Multiplication" class="external"&gt;chapter on Karatsuba Multiplication&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Gaudry et al, &lt;a href="http://www.loria.fr/~gaudry/publis/issac07.pdf" class="external"&gt;A GMP-based Implementation of Schönhage-Strassen’s Large Integer Multiplication Algorithm&lt;/a&gt;.  The title says it all.&lt;/li&gt;
&lt;li&gt;Martin Fürer, &lt;a href="http://wwwmath.uni-muenster.de/u/cl/WS2007-8/mult.pdf" class="external"&gt;Faster Integer Multiplication&lt;/a&gt;.  This paper describes what is currently the fastest known algorithm for multiplying extremely large numbers (based on FFT).  This is asymptotically fastest, but for practical bignum sizes, Schönhage-Strassen remains king.&lt;/li&gt;
&lt;li&gt;Yan-Bin Jia, &lt;a href="http://web.cs.iastate.edu/~cs577/handouts/polymultiply.pdf" class="external"&gt;Polynomial Multiplication and Fast Fourier Transform&lt;/a&gt;.  Lab notes for a CS course on problem solving techniques.  Pretty terse, but might be helpful in understanding how FFT works.&lt;/li&gt;
&lt;li&gt;Burnikel &amp;amp; Ziegler, &lt;a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.47.565&amp;amp;rep=rep1&amp;amp;type=pdf" class="external"&gt;Fast Recursive Division&lt;/a&gt;.  The original paper on this algorithm.&lt;/li&gt;
&lt;li&gt;Karl Hasselstrom, &lt;a href="http://bioinfo.ict.ac.cn/~dbu/AlgorithmCourses/Lectures/Hasselstrom2003.pdf" class="external"&gt;Fast Division of Large Integers&lt;/a&gt;.  This paper compares Newton's algorithm, the Burnikel-Ziegler algorithm and something called &amp;quot;Barret's Algorithm&amp;quot;.  The conclusion seems to be that Burnikel-Ziegler is usually fastest.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deamentiaemundi.wordpress.com/2014/11/16/multiple-precision-in-javascript-fast-division-i/" class="external"&gt;Deamentiaemundi's blog post&lt;/a&gt; about implementing Burnikel-Ziegler in JavaScript, including code.&lt;/li&gt;&lt;/ul&gt;</content>
    <id>tag:more-magic,2016-10-15:/posts/numeric-tower-part-3.html</id>
    <published>2016-10-15T18:08:42Z</published>
    <title type="text">CHICKEN's numeric tower: part 3</title>
    <updated>2016-10-15T18:08:42Z</updated>
    <link href="https://www.more-magic.net/posts/numeric-tower-part-3.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;This is the second part documenting my journey to add full numeric tower support to CHICKEN core.  In this post I explain some of the basic algorithms.  You'll need to understand these before going on to the next part, which deals with fancier versions of these algorithms.&lt;/p&gt;&lt;a href="#classical-numerical-algorithms"&gt;
&lt;h2 id="classical-numerical-algorithms"&gt;Classical numerical algorithms&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Like I mentioned in my previous post, the Scheme48 numerical code used only the so-called &amp;quot;classical&amp;quot; algorithms.  Comments in the Scheme48 code refer to Donald Knuth's seminal work, &lt;a href="http://www-cs-faculty.stanford.edu/~knuth/taocp.html" class="external"&gt;The Art of Computer Programming&lt;/a&gt;, Volume 2, chapter 4.  Interestingly, after these classical algorithms, Knuth explains a few faster algorithms, but Scheme48 did not implement these.&lt;/p&gt;&lt;a href="#addition-and-subtraction"&gt;
&lt;h3 id="addition-and-subtraction"&gt;Addition and subtraction&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Addition and subtraction are extremely simple algorithms: you simply loop over the limbs of both numbers simultaneously, and add them together, taking care to propagate the carry or borrow from the previous position.  This is the same algorithm you learned in primary school.  The difference is that the computer can add a whole machine word, while at school you would handle one decimal position at a time. This is &lt;tt&gt;O(n)&lt;/tt&gt; in complexity:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/addition-algorithm.svg" /&gt;&lt;/p&gt;
&lt;p&gt;For subtraction the algorithm is the same, except it uses borrowing instead of carrying.  You might wonder what happens if the value being subtracted is bigger than the one being subtracted from.  If those numbers are both positive, that results in a negative number, but when subtracting a negative number from a smaller positive number, its result would be positive.&lt;/p&gt;
&lt;p&gt;The solution is simple in case you're using unsigned representation with explicit sign: You compare the absolute values first.  If the second value is larger than the first, you swap them first.  Then you subtract them and toggle the sign of the result: If &lt;tt&gt;a - b = x&lt;/tt&gt;, then multiplying all factors by -1 gives: &lt;tt&gt;-a + b = -x&lt;/tt&gt;, or simply &lt;tt&gt;b - a = -x&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;As far as I'm aware, the primary school algorithm is &lt;i&gt;it&lt;/i&gt;.  There are no shortcuts, and no quicker ways around it.  However, Scheme48 used a surprising representation for their bignums: the limbs inside the bignum did not make use of the top two bits in the machine word. Presumably they did this for portability and correctness.  You see, in C, &lt;a href="https://www.securecoding.cert.org/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow" class="external"&gt;signed overflow is undefined&lt;/a&gt;, just so compilers can eke out a little more performance.  I think this is completely ridiculous, and it's another source of security issues, but that's what life with C is like.&lt;/p&gt;
&lt;p&gt;However, CHICKEN uses the &lt;tt&gt;-fwrapv&lt;/tt&gt; compiler option to enforce sane overflow behaviour.  That means CHICKEN bignums are free to use all available bits in a machine word.  This representation will also use slightly less memory for really large bignums, especially on 32-bit systems.  But, more importantly, it's faster because there's less masking and checking going on.  Here's the heart of Scheme48's bignum addition:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="symbol"&gt;while&lt;/span&gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;scan_y &amp;lt; end_y&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  sum = &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;*scan_x++&lt;/span&gt;)&lt;/span&gt; + &lt;span class="paren3"&gt;(&lt;span class="default"&gt;*scan_y++&lt;/span&gt;)&lt;/span&gt; + carry&lt;/span&gt;)&lt;/span&gt;;
  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;sum &amp;lt; BIGNUM_RADIX&lt;/span&gt;)&lt;/span&gt;     &lt;span class="comment"&gt;/* No overflow */&lt;/span&gt;
    &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
      &lt;span class="paren3"&gt;(&lt;span class="default"&gt;*scan_r++&lt;/span&gt;)&lt;/span&gt; = sum;
      carry = 0;
    &lt;/span&gt;}&lt;/span&gt;
  &lt;span class="symbol"&gt;else&lt;/span&gt;                        &lt;span class="comment"&gt;/* Overflow, adjust and set carry */&lt;/span&gt;
    &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
      &lt;span class="paren3"&gt;(&lt;span class="default"&gt;*scan_r++&lt;/span&gt;)&lt;/span&gt; = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;sum - BIGNUM_RADIX&lt;/span&gt;)&lt;/span&gt;;   &lt;span class="comment"&gt;/* sum modulo radix */&lt;/span&gt;
      carry = 1;
    &lt;/span&gt;}&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;And here is CHICKEN's:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="symbol"&gt;while&lt;/span&gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;scan_y &amp;lt; end_y&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  digit = *scan_r;
  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;carry&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    sum = digit + *scan_y++ + 1;
    carry = sum &amp;lt;= digit; &lt;span class="comment"&gt;/* Overflow if wrapped result is smaller or equal */&lt;/span&gt;
  &lt;/span&gt;}&lt;/span&gt; &lt;span class="symbol"&gt;else&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    sum = digit + *scan_y++;
    carry = sum &amp;lt; digit;  &lt;span class="comment"&gt;/* Overflow if wrapped result is smaller */&lt;/span&gt;
  &lt;/span&gt;}&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;*scan_r++&lt;/span&gt;)&lt;/span&gt; = sum;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Aside from the difference in coding style, you can see that Scheme48 needs to adjust the result if we got a carry.  The &lt;tt&gt;BIGNUM_RADIX&lt;/tt&gt; is the maximum bignum digit value plus one.  In terms of instructions, this masking and checking doesn't make &lt;i&gt;that&lt;/i&gt; much of a difference, surprisingly enough.&lt;/p&gt;
&lt;p&gt;But while tweaking this algorithm, I discovered that a nice performance improvement could be gained: First, copy the larger bignum to the result bignum, and then you loop over the second bignum, adding its limbs to the result's limbs, modifying it in-place.  I suppose this is faster because you're only manipulating two pointers at a time rather than three.  This is why &lt;tt&gt;scan_x&lt;/tt&gt; is not used in the CHICKEN version.  This requires &lt;tt&gt;memcpy&lt;/tt&gt; to be fast, so on some systems, the CHICKEN approach can potentially be slower than the Scheme48 one.&lt;/p&gt;&lt;a href="#multiplication"&gt;
&lt;h3 id="multiplication"&gt;Multiplication&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Multiplication is where things start to get more interesting.  The classical algorithm is still pretty basic, but much slower because it's &lt;tt&gt;O(n²)&lt;/tt&gt; in complexity.  This is because in this algorithm, we multiply each position in the first number by &lt;i&gt;every&lt;/i&gt; position in the other number, in a nested loop:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/multiplication-algorithm.svg" /&gt;&lt;/p&gt;
&lt;p&gt;As the graphic attempts to clarify, we take only half-digits when multiplying, because the result must fit a single digit.  This slows things down even further, because we can only iterate over the limbs at half speed.  In Scheme48's code, it looked like this:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="special"&gt;#define x_digit x_digit_high
&lt;/span&gt;&lt;span class="special"&gt;#define y_digit y_digit_high
&lt;/span&gt;&lt;span class="special"&gt;#define product_high carry
&lt;/span&gt;&lt;span class="symbol"&gt;while&lt;/span&gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;scan_x &amp;lt; end_x&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
    x_digit = &lt;span class="paren2"&gt;(&lt;span class="default"&gt;*scan_x++&lt;/span&gt;)&lt;/span&gt;;
    x_digit_low = &lt;span class="paren2"&gt;(&lt;span class="default"&gt;HD_LOW &lt;span class="paren3"&gt;(&lt;span class="default"&gt;x_digit&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
    x_digit_high = &lt;span class="paren2"&gt;(&lt;span class="default"&gt;HD_HIGH &lt;span class="paren3"&gt;(&lt;span class="default"&gt;x_digit&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
    carry = 0;
    scan_y = start_y;
    scan_r = &lt;span class="paren2"&gt;(&lt;span class="default"&gt;start_r++&lt;/span&gt;)&lt;/span&gt;;
    &lt;span class="symbol"&gt;while&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;scan_y &amp;lt; end_y&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
        y_digit = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;*scan_y++&lt;/span&gt;)&lt;/span&gt;;
        y_digit_low = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;HD_LOW &lt;span class="paren4"&gt;(&lt;span class="default"&gt;y_digit&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
        y_digit_high = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;HD_HIGH &lt;span class="paren4"&gt;(&lt;span class="default"&gt;y_digit&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
        product_low =
          &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;*scan_r&lt;/span&gt;)&lt;/span&gt; +
           &lt;span class="paren4"&gt;(&lt;span class="default"&gt;x_digit_low * y_digit_low&lt;/span&gt;)&lt;/span&gt; +
           &lt;span class="paren4"&gt;(&lt;span class="default"&gt;HD_LOW &lt;span class="paren5"&gt;(&lt;span class="default"&gt;carry&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
        product_high =
          &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;x_digit_high * y_digit_low&lt;/span&gt;)&lt;/span&gt; +
           &lt;span class="paren4"&gt;(&lt;span class="default"&gt;x_digit_low * y_digit_high&lt;/span&gt;)&lt;/span&gt; +
           &lt;span class="paren4"&gt;(&lt;span class="default"&gt;HD_HIGH &lt;span class="paren5"&gt;(&lt;span class="default"&gt;product_low&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; +
           &lt;span class="paren4"&gt;(&lt;span class="default"&gt;HD_HIGH &lt;span class="paren5"&gt;(&lt;span class="default"&gt;carry&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
        &lt;span class="paren3"&gt;(&lt;span class="default"&gt;*scan_r++&lt;/span&gt;)&lt;/span&gt; =
          &lt;span class="paren3"&gt;(&lt;span class="default"&gt;HD_CONS &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;HD_LOW &lt;span class="paren6"&gt;(&lt;span class="default"&gt;product_high&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;, &lt;span class="paren5"&gt;(&lt;span class="default"&gt;HD_LOW &lt;span class="paren6"&gt;(&lt;span class="default"&gt;product_low&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
        carry =
          &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;x_digit_high * y_digit_high&lt;/span&gt;)&lt;/span&gt; +
           &lt;span class="paren4"&gt;(&lt;span class="default"&gt;HD_HIGH &lt;span class="paren5"&gt;(&lt;span class="default"&gt;product_high&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
      &lt;/span&gt;}&lt;/span&gt;
    &lt;span class="paren2"&gt;(&lt;span class="default"&gt;*scan_r&lt;/span&gt;)&lt;/span&gt; += carry;
  &lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;tt&gt;#define&lt;/tt&gt; statements at the start are rather interesting, and seem to have been meticulously chosen to maximise re-use of variables. This was probably done to cajole inefficient compilers into re-using registers.  Some of the bignum code is originally from 1986, when C compilers weren't very sophisticated!  The &lt;tt&gt;HD_CONS&lt;/tt&gt; macro combines two halfwords together, while the &lt;tt&gt;HD_LOW&lt;/tt&gt; and &lt;tt&gt;HD_HIGH&lt;/tt&gt; extract the low and high halfword from a machine word, respectively:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="special"&gt;#define HD_LOW(digit) ((digit) &amp;amp; BIGNUM_HALF_DIGIT_MASK)
&lt;/span&gt;&lt;span class="special"&gt;#define HD_HIGH(digit) ((digit) &amp;gt;&amp;gt; BIGNUM_HALF_DIGIT_LENGTH)
&lt;/span&gt;&lt;span class="special"&gt;#define HD_CONS(high, low) (((high) &amp;lt;&amp;lt; BIGNUM_HALF_DIGIT_LENGTH) | (low))&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Remember, Scheme48 bignum digits use only 30 bits on a 32-bit machine and 62 bits on a 64-bit machine, so the masking and shifting is required.  Because CHICKEN bignum digits now used the full machine word, I was able to replace it with another, much shorter implementation, which relies on &amp;quot;automatic&amp;quot; truncation of machine words:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="comment"&gt;/* From Hacker&amp;#x27;s Delight, Figure 8-1 (top part) */&lt;/span&gt;
&lt;span class="symbol"&gt;for&lt;/span&gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;j = 0; j &amp;lt; length_y; ++j&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  yj = C_uhword_ref&lt;span class="paren2"&gt;(&lt;span class="default"&gt;yd, j&lt;/span&gt;)&lt;/span&gt;;
  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;yj == 0&lt;/span&gt;)&lt;/span&gt; continue;
  carry = 0;
  &lt;span class="symbol"&gt;for&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;i = 0; i &amp;lt; length_x; ++i&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    product = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_uword&lt;/span&gt;)&lt;/span&gt;C_uhword_ref&lt;span class="paren3"&gt;(&lt;span class="default"&gt;xd, i&lt;/span&gt;)&lt;/span&gt; * yj +
              &lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_uword&lt;/span&gt;)&lt;/span&gt;C_uhword_ref&lt;span class="paren3"&gt;(&lt;span class="default"&gt;rd, i + j&lt;/span&gt;)&lt;/span&gt; + carry;
    C_uhword_set&lt;span class="paren3"&gt;(&lt;span class="default"&gt;rd, i + j, product&lt;/span&gt;)&lt;/span&gt;;
    carry = C_BIGNUM_DIGIT_HI_HALF&lt;span class="paren3"&gt;(&lt;span class="default"&gt;product&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt;
  C_uhword_set&lt;span class="paren2"&gt;(&lt;span class="default"&gt;rd, j + length_x, carry&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;As the comment says, this code is adapted from the fantastic booklet &lt;a href="http://www.hackersdelight.org/" class="external"&gt;&amp;quot;Hacker's Delight&amp;quot;&lt;/a&gt; by Henry S. Warren, so any elegance you see in this code is not due to me!  The &lt;a href="http://www.hackersdelight.org/hdcodetxt/mulmnu.c.txt" class="external"&gt;original code&lt;/a&gt; is even more elegant, but it assumes little-endian order of bignum digits &lt;i&gt;and&lt;/i&gt; the halfwords within these digits.  On big endian machines the halfwords will be swapped within their machine words, so I introduced &lt;tt&gt;C_uhword_ref&lt;/tt&gt; and &lt;tt&gt;C_uhword_set&lt;/tt&gt;, which are ugly macros to select the higher/lower halfword of the relevant machine word:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="comment"&gt;/* The bignum digit representation is fullword- little endian, so on
 * LE machines the halfdigits are numbered in the same order.  On BE
 * machines, we must swap the odd and even positions.
 */&lt;/span&gt;
&lt;span class="special"&gt;#ifdef C_BIG_ENDIAN
&lt;/span&gt;&lt;span class="special"&gt;#define C_uhword_ref(x, p)           ((C_uhword *)(x))[(p)^1]
&lt;/span&gt;&lt;span class="special"&gt;#else
&lt;/span&gt;&lt;span class="special"&gt;#define C_uhword_ref(x, p)           ((C_uhword *)(x))[(p)]
&lt;/span&gt;&lt;span class="special"&gt;#endif
&lt;/span&gt;&lt;span class="special"&gt;#define C_uhword_set(x, p, d)        (C_uhword_ref(x,p) = (d))&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;tt&gt;(C_uhword *)&lt;/tt&gt; casts here ensure that only a halfword is extracted.  Most machines have an instruction to fetch a halfword into a register, which is much faster than masking it out.  So, even if it's ugly and hacky, I vastly prefer this over the Scheme48 code.&lt;/p&gt;&lt;a href="#division"&gt;
&lt;h3 id="division"&gt;Division&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Oh boy, where to start?  The above algorithms are so simple, but division, now that's quite a can of worms.  To make things worse, many textbooks (including Knuth) gloss over important details, assuming that readers can figure it out on their own.&lt;/p&gt;
&lt;p&gt;The first problem is that, unlike the above algorithms, the traditional &lt;i&gt;pen and paper&lt;/i&gt;-algorithm doesn't translate well to the computer.  Let's look at an example division, performed by hand as you would have learned it in primary school.  Here, we divide 543456 (the &lt;i&gt;dividend&lt;/i&gt; or &lt;i&gt;numerator&lt;/i&gt;) by 344 (the &lt;i&gt;divisor&lt;/i&gt; or &lt;i&gt;denominator&lt;/i&gt;):&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/school-division-algorithm.svg" /&gt;&lt;/p&gt;
&lt;p&gt;The notation might differ slightly from what you're used to (different schools use different notations, apparently), but the algorithm should be familiar: Given a denominator of &lt;tt&gt;n&lt;/tt&gt; digits, you take &lt;tt&gt;n+1&lt;/tt&gt; digits from the numerator (but &lt;tt&gt;n&lt;/tt&gt; in the first step!), then divide them by the denominator.  You write the quotient on the right.  Then you subtract the remainder from the digits you took from the numerator, and you continue with the next digit, until you hit the last digit of the numerator.  The final subtraction gives you the remainder at the bottom, and the digits you wrote on the right together form the quotient.&lt;/p&gt;
&lt;p&gt;There is a problem with this &amp;quot;algorithm&amp;quot;, though: it requires you to divide each numerator part by the &lt;i&gt;entire&lt;/i&gt; denominator.  If the denominator is a bignum, you're still dividing one bignum by another! Using this algorithm recursively won't work either, because it doesn't reduce the denominator's size.&lt;/p&gt;
&lt;p&gt;However, it turns out that you can &lt;i&gt;guess&lt;/i&gt; the results of these intermediate divisions, based on the first few digits of both numbers. Intuitively, you can get a pretty good guess of how many times a number fits in another by doing a &lt;i&gt;trial division&lt;/i&gt; of their leading digits.&lt;/p&gt;
&lt;p&gt;For example, a number like &lt;tt&gt;3xx&lt;/tt&gt; can fit about &lt;tt&gt;2x&lt;/tt&gt; times in a number like &lt;tt&gt;7xxx&lt;/tt&gt;.  In other words, our &lt;i&gt;guess&lt;/i&gt; is &lt;tt&gt;7/3 = 2&lt;/tt&gt;. For example, the number &lt;tt&gt;300&lt;/tt&gt; will fit &lt;tt&gt;23&lt;/tt&gt; times in &lt;tt&gt;7000&lt;/tt&gt;. This guess isn't completely accurate: for example, the number &lt;tt&gt;399&lt;/tt&gt; will fit only &lt;tt&gt;17&lt;/tt&gt; times in &lt;tt&gt;7000&lt;/tt&gt;. Note that the leading digit is now a &lt;tt&gt;1&lt;/tt&gt; instead of a &lt;tt&gt;2&lt;/tt&gt;, which means our guess was bad.  So in some cases we need to correct the guess.  Note that a guess may never exceed &lt;tt&gt;9&lt;/tt&gt;, because we're calculating &lt;i&gt;one&lt;/i&gt; decimal position of the quotient.  All this leads to the following relatively simple algorithm:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Make a guess based on trial division of the leading digits as described above;&lt;/li&gt;
&lt;li&gt;Multiply the denominator by the guess, to get a result;&lt;/li&gt;
&lt;li&gt;Subtract this result from the numerator, &lt;i&gt;but&lt;/i&gt;:&lt;/li&gt;
&lt;li&gt;If the subtraction goes below zero, add back the denominator and adjust the guess.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;This algorithm would work, but it takes many iterations.  It can be improved by taking into account &lt;i&gt;two&lt;/i&gt; leading digits of the denominator, instead of one.  This improves the accuracy of the guess, and it can be done easily if we only use halfdigits in our calculation (which we'll have to do anyway to avoid overflow when multiplying). In the picture below, for simplicity and brevity, each digit represents one halfword.&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/automated-division-algorithm.svg" /&gt;&lt;/p&gt;
&lt;p&gt;The picture above is pretty complicated!  I hope it clarifies the algorithm a little. The picture clearly shows two places where this algorithm guessed wrong, in which case we need to &lt;b&gt;adjust&lt;/b&gt; some values (shown in red).&lt;/p&gt;
&lt;p&gt;To understand the algorithm, first note the highlighted quotient digits with a question mark below them.  These indicate that the quotient digit is a guess.&lt;/p&gt;
&lt;p&gt;We tentatively multiply this guess by the first halfdigit of the denominator, and subtract it from the current remainder, giving a result in green.  Then, we append the next digit from the denominator (in blue) to the result we just got.  Finally, we multiply the next digit from the numerator (yellow) by its first digit, and see if the number is less than the combined intermediate remainder.  This means the guess was correct; otherwise the guess is incorrect, because the remainder would be negative.&lt;/p&gt;
&lt;p&gt;If the guess was wrong, we need to adjust the guess by subtracting one and performing the check again until the guess is correct.  You can see this happening near the bottom of the first column in the above picture.&lt;/p&gt;
&lt;p&gt;Once we have a correct guess based on the first two halfdigits, we go ahead and calculate the remainder.  To do this, we multiply the full &lt;tt&gt;n&lt;/tt&gt; digits of the denominator by the guess, and subtract the first &lt;tt&gt;n&lt;/tt&gt; digits of the remaining numerator.  All this can be done simultaneously, in &lt;tt&gt;O(n)&lt;/tt&gt;, even!&lt;/p&gt;
&lt;p&gt;Unfortunately, after having calculated the remainder, it can turn out negative.  This means the original guess was bad after all!  In this case we must make a last-minute adjustment, by subtracting one from the quotient, and then adding the denominator to the remainder.  This is shown in the picture in the first two steps of the second column.&lt;/p&gt;
&lt;p&gt;The actual implementation of this horribly complicated algorithm in Scheme48 was also &lt;a href="http://bugs.call-cc.org/browser/project/release/4/numbers/trunk/numbers-c.c?rev=31291#L1045" class="external"&gt;very complex and extremely long&lt;/a&gt; (it's all of the stuff between lines 1045 and 1383).  So, instead of attempting to understand and rework this to be faster and more consistent with CHICKEN core, once again I opted to steal &lt;a href="http://www.hackersdelight.org/hdcodetxt/divmnu64.c.txt" class="external"&gt;an implementation from Hacker's Delight&lt;/a&gt;.  It looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="symbol"&gt;static&lt;/span&gt; C_regparm &lt;span class="symbol"&gt;void&lt;/span&gt;
bignum_destructive_divide_normalized&lt;span class="paren1"&gt;(&lt;span class="default"&gt;C_word big_u, C_word big_v, C_word big_q&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  C_uword *v = C_bignum_digits&lt;span class="paren2"&gt;(&lt;span class="default"&gt;big_v&lt;/span&gt;)&lt;/span&gt;,
          *u = C_bignum_digits&lt;span class="paren2"&gt;(&lt;span class="default"&gt;big_u&lt;/span&gt;)&lt;/span&gt;,
          *q = big_q == C_SCHEME_UNDEFINED ? NULL : C_bignum_digits&lt;span class="paren2"&gt;(&lt;span class="default"&gt;big_q&lt;/span&gt;)&lt;/span&gt;,
           p,               &lt;span class="comment"&gt;/* product of estimated quotient &amp;amp; &amp;quot;denominator&amp;quot; */&lt;/span&gt;
           hat, qhat, rhat, &lt;span class="comment"&gt;/* estimated quotient and remainder digit */&lt;/span&gt;
           vn_1, vn_2;      &lt;span class="comment"&gt;/* &amp;quot;cached&amp;quot; values v[n-1], v[n-2] */&lt;/span&gt;
  C_word t, k;              &lt;span class="comment"&gt;/* Two helpers: temp/final remainder and &amp;quot;borrow&amp;quot; */&lt;/span&gt;
  &lt;span class="comment"&gt;/* We use plain ints here, which theoretically may not be enough on
   * 64-bit for an insanely huge number, but it is a _lot_ faster.
   */&lt;/span&gt;
  &lt;span class="symbol"&gt;int&lt;/span&gt; n = C_bignum_size&lt;span class="paren2"&gt;(&lt;span class="default"&gt;big_v&lt;/span&gt;)&lt;/span&gt; * 2,       &lt;span class="comment"&gt;/* in halfwords */&lt;/span&gt;
      m = &lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_bignum_size&lt;span class="paren3"&gt;(&lt;span class="default"&gt;big_u&lt;/span&gt;)&lt;/span&gt; * 2&lt;/span&gt;)&lt;/span&gt; - 2; &lt;span class="comment"&gt;/* Correct for extra digit */&lt;/span&gt;
  &lt;span class="symbol"&gt;int&lt;/span&gt; i, j;		                  &lt;span class="comment"&gt;/* Just two loop variables */&lt;/span&gt;

  &lt;span class="comment"&gt;/* Part 2 of Gauche&amp;#x27;s aforementioned trick: */&lt;/span&gt;
  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_uhword_ref&lt;span class="paren3"&gt;(&lt;span class="default"&gt;v, n-1&lt;/span&gt;)&lt;/span&gt; == 0&lt;/span&gt;)&lt;/span&gt; n--;

  &lt;span class="comment"&gt;/* These won&amp;#x27;t change during the loop, but are used in every step. */&lt;/span&gt;
  vn_1 = C_uhword_ref&lt;span class="paren2"&gt;(&lt;span class="default"&gt;v, n-1&lt;/span&gt;)&lt;/span&gt;;
  vn_2 = C_uhword_ref&lt;span class="paren2"&gt;(&lt;span class="default"&gt;v, n-2&lt;/span&gt;)&lt;/span&gt;;

  &lt;span class="comment"&gt;/* See also Hacker&amp;#x27;s Delight, Figure 9-1.  This is almost exactly that. */&lt;/span&gt;
  &lt;span class="symbol"&gt;for&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;j = m - n; j &amp;gt;= 0; j--&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    &lt;span class="comment"&gt;/* First, determine the initial guess: */&lt;/span&gt;
    hat = C_BIGNUM_DIGIT_COMBINE&lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_uhword_ref&lt;span class="paren4"&gt;(&lt;span class="default"&gt;u, j+n&lt;/span&gt;)&lt;/span&gt;, C_uhword_ref&lt;span class="paren4"&gt;(&lt;span class="default"&gt;u, j+n-1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
    &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;hat == 0&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren3"&gt;{&lt;span class="default"&gt;
      &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;q != NULL&lt;/span&gt;)&lt;/span&gt; C_uhword_set&lt;span class="paren4"&gt;(&lt;span class="default"&gt;q, j, 0&lt;/span&gt;)&lt;/span&gt;;
      continue;
    &lt;/span&gt;}&lt;/span&gt;
    qhat = hat / vn_1;
    rhat = hat % vn_1;

    &lt;span class="comment"&gt;/* Next, keep making early adjustments to the guess
     * until it matches the first two digits:
     */&lt;/span&gt;

    &lt;span class="comment"&gt;/* Two whiles is faster than one big check with an OR.  Thanks, Gauche! */&lt;/span&gt;
    &lt;span class="symbol"&gt;while&lt;/span&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;qhat &amp;gt;= &lt;span class="paren4"&gt;(&lt;span class="default"&gt;1UL &amp;lt;&amp;lt; C_BIGNUM_HALF_DIGIT_LENGTH&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren3"&gt;{&lt;span class="default"&gt; qhat--; rhat += vn_1; &lt;/span&gt;}&lt;/span&gt;
    &lt;span class="symbol"&gt;while&lt;/span&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;qhat * vn_2 &amp;gt; C_BIGNUM_DIGIT_COMBINE&lt;span class="paren4"&gt;(&lt;span class="default"&gt;rhat, C_uhword_ref&lt;span class="paren5"&gt;(&lt;span class="default"&gt;u, j+n-2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
	  &amp;amp;&amp;amp; rhat &amp;lt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;1UL &amp;lt;&amp;lt; C_BIGNUM_HALF_DIGIT_LENGTH&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren3"&gt;{&lt;span class="default"&gt;
      qhat--;
      rhat += vn_1;
    &lt;/span&gt;}&lt;/span&gt;

    &lt;span class="comment"&gt;/* Finally, multiply and subtract: */&lt;/span&gt;
    k = 0;
    &lt;span class="symbol"&gt;for&lt;/span&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;i = 0; i &amp;lt; n; i++&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren3"&gt;{&lt;span class="default"&gt;
      p = qhat * C_uhword_ref&lt;span class="paren4"&gt;(&lt;span class="default"&gt;v, i&lt;/span&gt;)&lt;/span&gt;;
      t = C_uhword_ref&lt;span class="paren4"&gt;(&lt;span class="default"&gt;u, i+j&lt;/span&gt;)&lt;/span&gt; - k - C_BIGNUM_DIGIT_LO_HALF&lt;span class="paren4"&gt;(&lt;span class="default"&gt;p&lt;/span&gt;)&lt;/span&gt;;
      C_uhword_set&lt;span class="paren4"&gt;(&lt;span class="default"&gt;u, i+j, t&lt;/span&gt;)&lt;/span&gt;;
      k = C_BIGNUM_DIGIT_HI_HALF&lt;span class="paren4"&gt;(&lt;span class="default"&gt;p&lt;/span&gt;)&lt;/span&gt; - &lt;span class="paren4"&gt;(&lt;span class="default"&gt;t &amp;gt;&amp;gt; C_BIGNUM_HALF_DIGIT_LENGTH&lt;/span&gt;)&lt;/span&gt;;
    &lt;/span&gt;}&lt;/span&gt;
    t = C_uhword_ref&lt;span class="paren3"&gt;(&lt;span class="default"&gt;u,j+n&lt;/span&gt;)&lt;/span&gt; - k;
    C_uhword_set&lt;span class="paren3"&gt;(&lt;span class="default"&gt;u, j+n, t&lt;/span&gt;)&lt;/span&gt;;

    &lt;span class="comment"&gt;/* Subtracted too much?
     * Make a late adjustment by adding back the denominator:
     */&lt;/span&gt;
    &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;t &amp;lt; 0&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren3"&gt;{&lt;span class="default"&gt;
      qhat--;
      k = 0;
      &lt;span class="symbol"&gt;for&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;i = 0; i &amp;lt; n; i++&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;{&lt;span class="default"&gt;
        t = &lt;span class="paren5"&gt;(&lt;span class="default"&gt;C_uword&lt;/span&gt;)&lt;/span&gt;C_uhword_ref&lt;span class="paren5"&gt;(&lt;span class="default"&gt;u, i+j&lt;/span&gt;)&lt;/span&gt; + C_uhword_ref&lt;span class="paren5"&gt;(&lt;span class="default"&gt;v, i&lt;/span&gt;)&lt;/span&gt; + k;
        C_uhword_set&lt;span class="paren5"&gt;(&lt;span class="default"&gt;u, i+j, t&lt;/span&gt;)&lt;/span&gt;;
	k = t &amp;gt;&amp;gt; C_BIGNUM_HALF_DIGIT_LENGTH;
      &lt;/span&gt;}&lt;/span&gt;
      C_uhword_set&lt;span class="paren4"&gt;(&lt;span class="default"&gt;u, j+n, &lt;span class="paren5"&gt;(&lt;span class="default"&gt;C_uhword_ref&lt;span class="paren6"&gt;(&lt;span class="default"&gt;u, j+n&lt;/span&gt;)&lt;/span&gt; + k&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
    &lt;/span&gt;}&lt;/span&gt;
    &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;q != NULL&lt;/span&gt;)&lt;/span&gt; C_uhword_set&lt;span class="paren3"&gt;(&lt;span class="default"&gt;q, j, qhat&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt; &lt;span class="comment"&gt;/* end of &amp;quot;j&amp;quot; loop */&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;There are some shoutouts to &lt;a href="http://practical-scheme.net/gauche/index.html" class="external"&gt;Gauche&lt;/a&gt;, which is a beautifully-crafted Scheme implementation in C.  The particular &amp;quot;trick&amp;quot; referred to here simplifies the calculation of our allocation sizes a little bit by ensuring we never shift more than a halfdigit when normalising (see next section).&lt;/p&gt;
&lt;p&gt;As you can see from the implementation, the &amp;quot;multiply and subtract&amp;quot; is actually done in one loop which scans over the remainder &lt;tt&gt;u&lt;/tt&gt; and denominator &lt;tt&gt;v&lt;/tt&gt; at the same time, so this is not &amp;quot;magic&amp;quot;; we can perform the multiply and subtract steps over the entire bignum in one efficient &lt;tt&gt;O(n)&lt;/tt&gt; loop.  Perhaps surprisingly, the overall algorithm is &lt;tt&gt;O(n²)&lt;/tt&gt;, just like multiplication.  Division is still much slower than multiplication because each &amp;quot;step&amp;quot; performs more operations (just look at the algorithms!).&lt;/p&gt;&lt;a href="#normalisation"&gt;
&lt;h3 id="normalisation"&gt;Normalisation&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;A real-world implementation of the above division algorithm will try to reduce the number of guess adjustments.  This is done by first &lt;i&gt;normalising&lt;/i&gt; or &lt;i&gt;scaling&lt;/i&gt; the numbers.  This is done by multiplying both the numerator and denominator with the same power of two before starting to do the division.  Afterwards, the remainder must be scaled back by dividing by that power of two.  Instead of multiplying and dividing, you can of course just shift the numbers.&lt;/p&gt;
&lt;p&gt;The number by which is multiplied depends on the numerator's first digit; it must be scaled up to be at least half of the base.  In base &lt;tt&gt;10&lt;/tt&gt;, you need to scale it up to at least &lt;tt&gt;5&lt;/tt&gt;, while in a &amp;quot;full machine word&amp;quot; base it's even easier: you simply shift the entire number so that the highest bit of the most significant limb is set. How Scheme48 did this:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;bignum_digit_type v1 = &lt;span class="paren1"&gt;(&lt;span class="default"&gt;BIGNUM_REF &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;denominator&lt;/span&gt;)&lt;/span&gt;, &lt;span class="paren3"&gt;(&lt;span class="default"&gt;length_d - 1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
&lt;span class="symbol"&gt;while&lt;/span&gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;v1 &amp;lt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;BIGNUM_RADIX / 2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;  &lt;span class="comment"&gt;/* Is the high bit set yet? */&lt;/span&gt;
  &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
    v1 &amp;lt;&amp;lt;= 1;
    shift += 1;
  &lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;In the CHICKEN version, we take a simpler approach by subtracting the integer length from the digit length, which effectively is the same as counting the number of leading zeroes (&amp;quot;nlz&amp;quot;):&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;C_uword v1 = *&lt;span class="paren1"&gt;(&lt;span class="default"&gt;C_bignum_digits&lt;span class="paren2"&gt;(&lt;span class="default"&gt;denominator&lt;/span&gt;)&lt;/span&gt; + length - 1&lt;/span&gt;)&lt;/span&gt;; 
shift = C_BIGNUM_DIGIT_LENGTH - C_ilen&lt;span class="paren1"&gt;(&lt;span class="default"&gt;v1&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* nlz */&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Then, both numbers are copied into temporary buffers which are shifted left in-place by the number of bits calculated here.&lt;/p&gt;
&lt;p&gt;Normalisation works by preventing the algorithm from &lt;i&gt;overshooting&lt;/i&gt;. Think about it: any guess may always be too high, never too low!  So if you scale the first digit to be as high as possible, you can't so easily make a guess that is too high.  It's weird, but the math seems to work out.&lt;/p&gt;&lt;a href="#a-reading-list-for-beginners"&gt;
&lt;h2 id="a-reading-list-for-beginners"&gt;A reading list for beginners&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;I am writing this blog post series mostly as a quick overview and introduction to the struggles and approaches taken in CHICKEN's bignum implementation.  It is not intended as a full-on tutorial.  If you are serious about implementing a full numeric tower (good for you!) or diving deeper into the CHICKEN code, you'll need more.  Unfortunately, &lt;i&gt;good&lt;/i&gt; and &lt;i&gt;easy to understand&lt;/i&gt; documentation is surprisingly hard to find, so here's a reading list to save you some effort.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Knuth's &lt;a href="http://www-cs-faculty.stanford.edu/~knuth/taocp.html" class="external"&gt;The Art of Computer Programming&lt;/a&gt;, Vol. 2: &lt;i&gt;Seminumerical Algorithms&lt;/i&gt;. The definitive reference.  Many will say that every self-respecting hacker should have read these books, but truth be told they're rather tough to get through.  But even if you do give up working through the books, they serve as great reference material.  Why are these books so tough?  They're math-heavy (especially the first book), and Knuth uses his own &amp;quot;hypothetical&amp;quot; &lt;a href="https://en.wikipedia.org/wiki/MIX" class="external"&gt;MIX architecture&lt;/a&gt; for all code examples and exercises.  Yes, everything is in assembly language! Nevertheless, the books are very thorough, and they're obviously written out of love for the craft.&lt;/li&gt;
&lt;li&gt;Tom St Denis's book &lt;a href="http://www.opensource.apple.com/source/Heimdal/Heimdal-172.18/lib/hcrypto/libtommath/tommath.pdf" class="external"&gt;Multi-Precision Math&lt;/a&gt; is much more gentle than Knuth's books.  This is the companion book for &lt;a href="http://www.libtom.org/LibTomMath/" class="external"&gt;LibTomMath&lt;/a&gt;, a public domain, well-commented bignum library, &lt;a href="http://www.libtom.org/about/" class="external"&gt;explicitly written&lt;/a&gt; to be easy to understand.  The book and library cover mostly classic algorithms, but there are also a handful of &amp;quot;advanced&amp;quot; algorithms, and several special-purpose optimised versions.&lt;/li&gt;
&lt;li&gt;Per Brinch Hansen's &lt;a href="http://brinch-hansen.net/papers/1994b.pdf" class="external"&gt;Multiple-Length Division Revisited: A Tour of the Minefield&lt;/a&gt;.  This little gem is helpful if you are having trouble following textbook explanations of the classical division algorithm.  It was written out of frustration with the poor quality of existing explanations.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://profs.info.uaic.ro/~mpnt/publications/tr03-02.pdf" class="external"&gt;MpNT: A Multi-Precision Number Package&lt;/a&gt; by Tiplea et al. is another overview of a library's algorithms.  This is a bit terser and more math-heavy than the LibTom book, but also covers several more advanced algorithms. This is a very good and complete reference.&lt;/li&gt;
&lt;li&gt;Finally, &lt;a href="https://members.loria.fr/PZimmermann/mca/pub226.html" class="external"&gt;Modern Computer Arithmetic&lt;/a&gt; by Richard Brent and Paul Zimmermann is probably the tersest, but also the most complete guide to efficient algorithms that I've found so far.  These guys know what they're talking about: this book truly covers the &amp;quot;state of the art&amp;quot;.  Only for advanced students of numerics :)&lt;/li&gt;
&lt;li&gt;As a bonus, if you're serious about efficiency: &lt;a href="https://gmplib.org/manual/Algorithms.html#Algorithms" class="external"&gt;The &amp;quot;algorithms&amp;quot; section of the GMP manual&lt;/a&gt;.  These are terse and incomplete, and you usually won't get a complete understanding just by reading them.  However, since GMP is the most popular implementation, it is also the fastest: Researchers usually create a proof of concept implementation for GMP and compare it to the existing algorithms. So, it is important to know which algorithms GMP is currently using, and then try to find better papers that explain them.&lt;/li&gt;&lt;/ul&gt;</content>
    <id>tag:more-magic,2016-10-13:/posts/numeric-tower-part-2.html</id>
    <published>2016-10-13T17:35:29Z</published>
    <title type="text">CHICKEN's numeric tower: part 2</title>
    <updated>2016-10-13T17:35:29Z</updated>
    <link href="https://www.more-magic.net/posts/numeric-tower-part-2.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;Originally, CHICKEN only supported fixnums (small integers) and flonums (floating-point numbers).  The upcoming CHICKEN 5 will support a full &lt;a href="https://en.wikipedia.org/wiki/Numeric_tower" class="external"&gt;numeric tower&lt;/a&gt;, adding arbitrary-length integers, rational numbers and complex numbers.  This is the first in a series of blog posts about my journey to make this a reality.  We'll start with a bit of background information.  Later parts will dive into the technical details.&lt;/p&gt;&lt;a href="#in-the-beginning-there-were-two-numerical-types"&gt;
&lt;h2 id="in-the-beginning-there-were-two-numerical-types"&gt;In the beginning, there were two numerical types&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Like I mentioned, CHICKEN originally only supported fixnums and flonums.  This is still the case in CHICKEN 4.  When a fixnum overflows, it is coerced into a flonum.  On 32-bit systems, this buys us 52 bits of precision, which is more than the 30 bits of precision fixnums offer:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; #;1&amp;gt; most-positive-fixnum
 1073741823
 #;2&amp;gt; (+ most-positive-fixnum 1)
 1073741824.0&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This works reasonably well, and is well-behaved until you go beyond the 52 bits supported by the floating-point representation:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; #;3&amp;gt; (flonum-print-precision 100)
 #;4&amp;gt; (expt 2 53)
 9007199254740992.0
 #;5&amp;gt; (+ (expt 2 53) 1)
 9007199254740992.0
 #;6&amp;gt; (= (expt 2 53) (+ (expt 2 53) 1))
 #t&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;On a 64-bit machine, overflow of the 62 bits of a fixnum to the 52 bits of a flonum is rather weird:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; #;1&amp;gt; (= most-positive-fixnum (- (+ most-positive-fixnum 1) 2))
 #t&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Since we only have fixnums and flonums, any attempt to enter a rational number will result in a flonum:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; #;1&amp;gt; 1/2
 0.5
 #;2&amp;gt; 1/3
 0.333333333333333&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Complex numbers are not supported at all:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; #;1&amp;gt; 1+2i
 
 Error: unbound variable: 1+2i&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Of course, some people still needed to work with complex numbers, so a &lt;a href="http://lists.gnu.org/archive/html/chicken-users/2004-08/msg00015.html" class="external"&gt;long time ago&lt;/a&gt;, Thomas Chust created the &amp;quot;&lt;a href="http://wiki.call-cc.org/eggref/3/complex" class="external"&gt;complex&lt;/a&gt;&amp;quot; egg.  This added complex number support to the reader, and the basic numeric operators were overridden to support complex numbers.  About a year later, Felix Winkelmann created the original version of the &amp;quot;&lt;a href="http://lists.gnu.org/archive/html/chicken-users/2005-04/msg00069.html" class="external"&gt;numbers&lt;/a&gt;&amp;quot; egg, using Thomas's code for complex numbers.  This added arbitrarily large integers (&amp;quot;bignums&amp;quot; in Lisp parlance) and rational number support via the &lt;a href="https://gmplib.org/" class="external"&gt;GNU MP&lt;/a&gt; library.  Thus, CHICKEN finally had a full numeric tower, and it was completely optional, too. Pretty awesome!&lt;/p&gt;&lt;a href="#cracks-start-to-show"&gt;
&lt;h2 id="cracks-start-to-show"&gt;Cracks start to show&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Unfortunately, it's not as awesome as it sounds.  There are some problems with having parts of the numeric tower as an add-on, instead of having it all in core:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In a Scheme with modules, &lt;tt&gt;+&lt;/tt&gt; from the &lt;tt&gt;scheme&lt;/tt&gt; module should always refer to the same procedure.  So if a module imports &lt;i&gt;that&lt;/i&gt; &lt;tt&gt;+&lt;/tt&gt; instead of the one from the &lt;tt&gt;numbers&lt;/tt&gt; module, it will not understand extended numeric types.  This means that you can't easily combine a library that uses &lt;tt&gt;numbers&lt;/tt&gt; with one that doesn't. If you pass a bignum to the library that does not use &lt;tt&gt;numbers&lt;/tt&gt;, it will raise an exception.  This is mostly a problem with Scheme itself, which doesn't have a clean way to define polymorphic procedures. This makes the numeric tower a built-in special case.  It is possible to mutate procedures, but allowing for that implies a big performance hit on all code, even if you &lt;i&gt;don't&lt;/i&gt; use the numbers egg.&lt;/li&gt;
&lt;li&gt;The numbers egg extends the reader to support extended numeric literals.  This means that if some code somewhere loads the numbers egg, the reader extension is active even though you didn't load numbers yourself.  This can cause confusion because normal numeric operations don't accept these numbers.  For an example, see &lt;a href="http://lists.gnu.org/archive/html/chicken-users/2016-01/msg00000.html" class="external"&gt;this bug report&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Speaking of extended numeric literals: the compiler doesn't know how to serialise those into the generated C code.  This means you can't compile Scheme code containing such literals.  You'd have to use &lt;tt&gt;string-&amp;gt;number&lt;/tt&gt; everywhere, instead.  I found a clever hack to make this work with the numbers egg, but it isn't fool-proof. For instance, it doesn't work when cross-compiling to a platform with different &lt;a href="https://en.wikipedia.org/wiki/Endianness" class="external"&gt;endianness&lt;/a&gt;, or if one platform is 32-bit and the other is 64-bit.&lt;/li&gt;
&lt;li&gt;The compiler can optimise tight loops by using inline C functions for primitive operations such as the built-in numerical procedures. A current weak spot of CHICKEN is that (as far as I know), eggs can't add such inline C function replacements.  So, any code that uses the numbers egg is doomed to have bad performance in critical loops.  I think making inlining of C functions available for user code would be a great project (hint, hint!).&lt;/li&gt;
&lt;li&gt;Because the FFI (foreign function interface) is built into the compiler, it doesn't support bignums.  This means 64-bit integers returned from C are converted to flonums, losing precision. Eggs can't hook into the FFI deeply enough to override this.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;One could argue that these are all language or implementation limitations.  On the one hand, that's a fair argument.  On the other hand, keeping everything &amp;quot;open&amp;quot; so it can be tweaked by the user prevents many optimisations.  It also makes the implementation more complex.  For instance, there are hooks in core specifically for the numbers egg, to support reading and writing extended literals.  The numeric tower needs deeper integration than most other things because numbers are a basic type, much like symbols, strings or lists.  So, it makes more sense to have this in the core system.&lt;/p&gt;&lt;a href="#the-start-of-my-quest"&gt;
&lt;h2 id="the-start-of-my-quest"&gt;The start of my quest&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Traditionally, Lisps have supported a full numeric tower.  At least since the &lt;a href="http://www.maclisp.info/pitmanual/number.html" class="external"&gt;MacLISP days&lt;/a&gt; (the early 1970s; see also &lt;a href="http://dreamsongs.com/Files/Hopl2.pdf" class="external"&gt;The History of Lisp&lt;/a&gt;), bignums have been pretty standard.  Scheme &lt;a href="http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2.1" class="external"&gt;formalises this in the standard&lt;/a&gt;, but it does not require full support for all numeric types.  Still, in my opinion any serious Lisp or Scheme implementation should support the full numerical tower.  It's one of those things that make Lisp unique and more cause for that famous smugness of us Lisp weenies.&lt;/p&gt;
&lt;p&gt;It is fantastic when a language supports arbitrarily large integers. Not having to worry about overflows helps prevent various &lt;a href="https://www.owasp.org/index.php/OWASP_Periodic_Table_of_Vulnerabilities_-_Integer_Overflow/Underflow" class="external"&gt;nasty security bugs&lt;/a&gt; (luckily, overflowing into flonums, like CHICKEN, mitigates most of these).  Bignums can also make it much easier to interact with native code, because integer width is never a problem.  It basically frees the programmer from having to think about &amp;quot;unimportant&amp;quot; low-level details.  Rational numbers (i.e., fractions like 1/2 or 3/5) and complex numbers are just icing on the cake that add a real feeling of &amp;quot;thoroughness&amp;quot; to Lisp.&lt;/p&gt;
&lt;p&gt;This idea, and the fact that other &amp;quot;proper&amp;quot; Scheme implementations support the full numeric tower out of the box always frustrated me. I believe people are less likely to take CHICKEN seriously as a full Scheme implementation.  Especially new users are often &lt;a href="http://lists.gnu.org/archive/html/chicken-users/2010-02/msg00003.html" class="external"&gt;surprised&lt;/a&gt; when CHICKEN &lt;a href="http://lists.gnu.org/archive/html/chicken-users/2013-03/msg00031.html" class="external"&gt;does&lt;/a&gt; &lt;a href="http://lists.gnu.org/archive/html/chicken-users/2012-11/msg00048.html" class="external"&gt;not&lt;/a&gt; &lt;a href="http://lists.gnu.org/archive/html/chicken-users/2005-01/msg00057.html" class="external"&gt;work&lt;/a&gt; as &lt;a href="http://lists.gnu.org/archive/html/chicken-users/2011-06/msg00010.html" class="external"&gt;expected&lt;/a&gt;. Tutorials don't mention that the numeric tower is partly optional!&lt;/p&gt;
&lt;p&gt;More experienced users were also frustrated with the limitations of having numbers as a separate egg, like you can see for example in &lt;a href="http://lists.gnu.org/archive/html/chicken-users/2009-10/msg00000.html" class="external"&gt;this thread&lt;/a&gt;.  In it, some of the problems are indicated, and it is also &lt;a href="http://lists.gnu.org/archive/html/chicken-users/2009-10/msg00011.html" class="external"&gt;made clear&lt;/a&gt; why a GNU MP-based implementation should not be part of CHICKEN.&lt;/p&gt;
&lt;p&gt;From all of this, I decided that the best way to get bignums into core would be to start with finding a good BSD-licensed implementation. Then I could replace GMP with this new implementation in the numbers egg, tweak it to use CHICKEN's naming conventions and finally integrate the new code into core.  How hard could it be, really? Little did I suspect that 5 years later, the code would finally be introduced to core!&lt;/p&gt;&lt;a href="#a-very-slow-but-bsd-licensed-implementation"&gt;
&lt;h2 id="a-very-slow-but-bsd-licensed-implementation"&gt;A very slow, but BSD-licensed implementation&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Finding a BSD-licensed bignum implementation is not very difficult, and I quickly settled on the &lt;a href="http://www.s48.org" class="external"&gt;Scheme48&lt;/a&gt; implementation, which was originally taken from MIT Scheme.  I've always admired Scheme48 for its extremely clean and easy to understand code base, and CHICKEN core already used the &lt;tt&gt;syntax-rules&lt;/tt&gt; implementation from Scheme48, so it made a lot of sense to use their code.  Unfortunately, it turned out that the implementation was extremely inefficient, especially when dealing with rational numbers (&amp;quot;ratnums&amp;quot;).  After a few weeks of intensive hacking to fix the worst problems, &lt;a href="http://lists.gnu.org/archive/html/chicken-users/2010-03/msg00038.html" class="external"&gt;it was finally ready&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This new implementation was much more efficient than the GMP-based numbers egg, but that's only because the GMP-based version relied heavily on &lt;i&gt;finalizers&lt;/i&gt; to clean up memory.  The new version integrated properly with the CHICKEN garbage collector.  This reduced a whole lot of overhead.  Having said that, GMP &lt;i&gt;itself&lt;/i&gt; is the fastest bignum implementation you'll ever find, so if you can at all get away with using it in your project, do so!&lt;/p&gt;&lt;a href="#chicken-5-is-announced"&gt;
&lt;h2 id="chicken-5-is-announced"&gt;CHICKEN 5 is announced&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;The CHICKEN core team (of which I'm a member) decided that CHICKEN 5 should be a clean break, with no backwards compatibility.  We wanted to finally restructure the core libraries, which had become rather messy, and change a few confusing aspects about modules.  Doing this with backwards compatibility would sap too much development energy and possibly result in an even bigger mess.  When this decision was made, I decided that this would be the perfect opportunity to finally integrate the numbers egg into core.&lt;/p&gt;
&lt;p&gt;I had been &lt;a href="http://lists.gnu.org/archive/html/chicken-users/2012-05/msg00009.html" class="external"&gt;working&lt;/a&gt; on the numbers egg on and off over the past years, hoping for a good moment to add it to core.  When the opportunity presented itself, at first I naively thought a few tweaks would suffice to integrate it.  I thought I only had to make some name changes and rearrange some functions.  The Scheme48 code base used very descriptive and highly abstract naming, whereas CHICKEN uses terse names and has both inline and CPS variants for primitive operations.  Besides, quite a bit of code in the numbers egg was purely in Scheme, whereas CHICKEN has a more-or-less official C API.  So, I had to convert some of the functions to C.  This would probably also result in some performance improvements.&lt;/p&gt;&lt;a href="#small-changes-lead-to-a-total-rewrite"&gt;
&lt;h2 id="small-changes-lead-to-a-total-rewrite"&gt;Small changes lead to a total rewrite&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;During the conversion to C, I noticed various opportunities for performance improvements.  For instance, the Scheme48 code still relied on &lt;tt&gt;malloc()&lt;/tt&gt; to allocate temporary numbers in several places.  Where this was done, the final result of an operation would then be allocated into GC-managed memory and the temporary buffer was immediately freed.&lt;/p&gt;
&lt;p&gt;Rewriting the code to allocate directly in GC-able memory resulted in quite the restructuring of the code, because we'd need to have a restartable continuation at every point where an allocation would take place.  For example, here's the code for negating a bignum:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="symbol"&gt;static&lt;/span&gt; &lt;span class="symbol"&gt;void&lt;/span&gt; big_neg&lt;span class="paren1"&gt;(&lt;span class="default"&gt;C_word c, C_word self, C_word k, C_word x&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  bignum_type big = big_of&lt;span class="paren2"&gt;(&lt;span class="default"&gt;x&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* Extract bignum data */&lt;/span&gt;
  C_word negated_big = bignum_new_sign&lt;span class="paren2"&gt;(&lt;span class="default"&gt;big, !&lt;span class="paren3"&gt;(&lt;span class="default"&gt;BIGNUM_NEGATIVE_P &lt;span class="paren4"&gt;(&lt;span class="default"&gt;big&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
  C_return_bignum&lt;span class="paren2"&gt;(&lt;span class="default"&gt;k, negated_big&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;

&lt;span class="symbol"&gt;static&lt;/span&gt; bignum_type bignum_new_sign&lt;span class="paren1"&gt;(&lt;span class="default"&gt;bignum_type bignum, &lt;span class="symbol"&gt;int&lt;/span&gt; negative_p&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  bignum_type result =
    &lt;span class="paren2"&gt;(&lt;span class="default"&gt;bignum_allocate &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;BIGNUM_LENGTH &lt;span class="paren5"&gt;(&lt;span class="default"&gt;bignum&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;, negative_p&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;  &lt;span class="comment"&gt;/* mallocs */&lt;/span&gt;
  bignum_destructive_copy &lt;span class="paren2"&gt;(&lt;span class="default"&gt;bignum, result&lt;/span&gt;)&lt;/span&gt;;  &lt;span class="comment"&gt;/* basically a manual memcpy */&lt;/span&gt;
  &lt;span class="symbol"&gt;return&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;result&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;It looks very simple, but a lot is going on under the hood.  The &lt;tt&gt;C_return_bignum&lt;/tt&gt; function contained all the &lt;a href="http://bugs.call-cc.org/browser/project/release/4/numbers/trunk/numbers-c.c?rev=31291#L113" class="external"&gt;hairy complexity&lt;/a&gt;; it would either convert the bignum to a fixnum, deallocate the bignum and call the passed continuation, or it would set up a continuation that would copy the bignum into a heap-allocated copy and deallocate the original bignum, and pass that to an allocation function.&lt;/p&gt;
&lt;p&gt;This was changed into the following, which uses the core's &lt;tt&gt;_u_&lt;/tt&gt; naming convention to indicate that the function is unsafe, i.e. it doesn't check its arguments:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="symbol"&gt;void&lt;/span&gt; C_ccall C_u_bignum_negate&lt;span class="paren1"&gt;(&lt;span class="default"&gt;C_word c, C_word self, C_word k, C_word x&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  C_word kab&lt;span class="paren2"&gt;[&lt;span class="default"&gt;C_SIZEOF_CLOSURE&lt;span class="paren3"&gt;(&lt;span class="default"&gt;3&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;]&lt;/span&gt;, *ka = kab, k2, negp, size;

  &lt;span class="comment"&gt;/* Create continuation k2, to call after allocation */&lt;/span&gt;
  k2 = C_closure&lt;span class="paren2"&gt;(&lt;span class="default"&gt;&amp;amp;ka, 3, &lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_word&lt;/span&gt;)&lt;/span&gt;bignum_negate_2, k, x&lt;/span&gt;)&lt;/span&gt;;
  
  negp = C_i_not&lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_u_i_bignum_negativep&lt;span class="paren3"&gt;(&lt;span class="default"&gt;x&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* Toggle sign */&lt;/span&gt;
  size = C_u_i_bignum_size&lt;span class="paren2"&gt;(&lt;span class="default"&gt;x&lt;/span&gt;)&lt;/span&gt;;
  C_allocate_bignum&lt;span class="paren2"&gt;(&lt;span class="default"&gt;3, &lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_word&lt;/span&gt;)&lt;/span&gt;NULL, k2, size, negp, C_SCHEME_FALSE&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;

&lt;span class="symbol"&gt;static&lt;/span&gt; &lt;span class="symbol"&gt;void&lt;/span&gt; bignum_negate_2&lt;span class="paren1"&gt;(&lt;span class="default"&gt;C_word c, C_word self, C_word new_big&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  C_word k = C_block_item&lt;span class="paren2"&gt;(&lt;span class="default"&gt;self, 1&lt;/span&gt;)&lt;/span&gt;, &lt;span class="comment"&gt;/* Extract original continuation */&lt;/span&gt;
         old_big = C_block_item&lt;span class="paren2"&gt;(&lt;span class="default"&gt;self, 2&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* Extract original bignum */&lt;/span&gt;

  &lt;span class="comment"&gt;/* Copy old bignum digits to newly allocated (negated) bignum */&lt;/span&gt;
  C_memcpy&lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_bignum_digits&lt;span class="paren3"&gt;(&lt;span class="default"&gt;new_big&lt;/span&gt;)&lt;/span&gt;, C_bignum_digits&lt;span class="paren3"&gt;(&lt;span class="default"&gt;old_big&lt;/span&gt;)&lt;/span&gt;,
           C_header_size&lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_internal_bignum&lt;span class="paren4"&gt;(&lt;span class="default"&gt;old_big&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;-C_wordstobytes&lt;span class="paren3"&gt;(&lt;span class="default"&gt;1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;

  C_kontinue&lt;span class="paren2"&gt;(&lt;span class="default"&gt;k, new_big&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* &amp;quot;Return&amp;quot; the new bignum by calling k with it */&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The new version looks hairier but does less, because it allocates the bignum directly into the nursery or the heap.  Because this may require a GC, it needs to have a continuation, which can be invoked from the GC's trampoline.  That's the reason this has to be cut into two separate C functions.  There are functions that allocate 2 bignums or even more, which I had to cut up into 3 or more functions!&lt;/p&gt;
&lt;p&gt;Besides using &amp;quot;native&amp;quot; naming conventions, this new version also gets rid of the unnecessary, un-CHICKENish &lt;tt&gt;bignum_type&lt;/tt&gt; abstraction. Instead, it uses only &lt;tt&gt;C_word&lt;/tt&gt; as its type.  This also removed the need for some questionable type casts.  Luckily, the final negating version that ended up in CHICKEN 5 is a lot simpler and again only one function, but that required a breakthrough in thinking that I hadn't had at this point yet.  I will discuss this breakthrough in the final post in this series.&lt;/p&gt;
&lt;p&gt;After having taken care of all the functions, very little remained of the original Scheme48 code.  It was completely mutilated!  Earlier I had to rewrite some of the Scheme code to improve performance, and now I was restructuring the C code.  To top it off, after studying other bignum implementations, it became clear that the Scheme48 code was pretty slow when compared to other Schemes.  It only implemented the &amp;quot;classical&amp;quot; algorithms, and it was optimised for readability, not speed.&lt;/p&gt;
&lt;p&gt;So, I studied up on better algorithms to make it perform more acceptably.  In the next few parts, I'll share with you a few things that I've learned.&lt;/p&gt;</content>
    <id>tag:more-magic,2016-10-10:/posts/numeric-tower-part-1.html</id>
    <published>2016-10-10T19:36:11Z</published>
    <title type="text">CHICKEN's numeric tower: part 1</title>
    <updated>2016-10-10T19:36:11Z</updated>
    <link href="https://www.more-magic.net/posts/numeric-tower-part-1.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;The recent trouble at GitHub, both &lt;a href="http://uk.businessinsider.com/github-the-full-inside-story-2016-2?r=US&amp;amp;IR=T" class="external"&gt;cultural changes within the company&lt;/a&gt; and &lt;a href="http://thenextweb.com/dd/2016/01/19/frustrated-developers-from-the-webs-biggest-projects-say-github-isnt-listening/" class="external"&gt;criticism from the community&lt;/a&gt;, reminded me how unstable the whole &amp;quot;free as in beer code hosting for the public good&amp;quot; idea really is.  The good part is that it motivated me to finally look into setting up personal hosting for my own projects, because how hard can it be, really?&lt;/p&gt;&lt;a href="#history-shows-code-hosting-is-unreliable"&gt;
&lt;h2 id="history-shows-code-hosting-is-unreliable"&gt;History shows: code hosting is unreliable&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;GitHub isn't unique in its problems, and switching away to a competitor with less problems isn't going to help in the long run. Besides, dormant projects will be irretrievably lost if GitHub ever shuts down unless someone happens to have a recent clone.  To show that the problem is bigger than GitHub, let's look at some events that I remember:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ages ago in internet time, in 2005, the Dutch government &lt;a href="https://www.bof.nl/2005/12/22/open-source-en-open-standaarden-bij-de-overheid/" class="external"&gt;set up a forge website&lt;/a&gt; to foster open source usage within the government.  &lt;a href="http://lists.sf.own-it.nl/pipermail/opentaal/2009-March/002867.html" class="external"&gt;In 2009, it went offline&lt;/a&gt;.  Most projects crawled off to SourceForge to die (including mine), but &lt;a href="https://github.com/libyal/libewf" class="external"&gt;some&lt;/a&gt; survive to this day.&lt;/li&gt;
&lt;li&gt;The year 2012 is actually not that long ago, and I clearly remember when &lt;a href="https://sourceforge.net/blog/berlios-projects-saved-moving-to-sourceforge-for-distribution/" class="external"&gt;BerliOS shut down&lt;/a&gt;.  I had used it for a project or two back when &lt;a href="https://subversion.apache.org/" class="external"&gt;Subversion&lt;/a&gt; was brand new.  They offered Subversion hosting when SourceForge and Savannah only offered &lt;a href="http://www.nongnu.org/cvs/" class="external"&gt;CVS&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;In 2014, I found out the hard way that &lt;a href="https://en.wikipedia.org/wiki/RubyForge" class="external"&gt;RubyForge&lt;/a&gt; had shut down a few months earlier.  I lost the complete commit history for a maintenance-mode project at work.&lt;/li&gt;
&lt;li&gt;In 2015, Gitorious got &lt;a href="https://about.gitlab.com/2015/03/03/gitlab-acquires-gitorious/" class="external"&gt;assimilated and subsequently shut down&lt;/a&gt; by GitLab.  At least, projects that didn't opt-in to a GitLab migration are available in read-only from their archive.&lt;/li&gt;
&lt;li&gt;Also in 2015, it became known that SourceForge &lt;a href="http://arstechnica.com/information-technology/2015/06/sourceforge-locked-in-projects-of-fleeing-users-cashed-in-on-malvertising/" class="external"&gt;was adding malware&lt;/a&gt; to popular free software downloads and lost all remaining goodwill from the community.  It's probably a matter of time before it dies completely, taking down with it an Alexandrian wealth of source code.&lt;/li&gt;
&lt;li&gt;At the beginning of 2015, &lt;a href="http://google-opensource.blogspot.com/2015/03/farewell-to-google-code.html" class="external"&gt;Google Code shut down&lt;/a&gt;.  Tarballs of archived projects will stay available until the end of the year, but after that the code will probably be gone forever.&lt;/li&gt;
&lt;li&gt;In 2017, &lt;a href="https://www.ubuntubuzz.com/2017/03/gna-software-hosting-will-shut-down.html" class="external"&gt;Gna!&lt;/a&gt; shut down.  It was lesser-known but still relatively popular in some circles (especially in France).&lt;/li&gt;
&lt;li&gt;In 2020, Bitbucket &lt;a href="https://bitbucket.org/blog/sunsetting-mercurial-support-in-bitbucket" class="external"&gt;axed Mercurial support&lt;/a&gt;, simply &lt;i&gt;deleting&lt;/i&gt; all Mercurial repositories (instead of, say, converting them to git).  Some projects in maintenance mode where the author moved on to other hosting sites for their projects got their public code (and issue tracker!) removed.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Except for Gitorious/GitLab, I have used and relied on every single one of these code hosting sites, either for personal or work-related projects, or as a contributor to someone else's project.&lt;/p&gt;&lt;a href="#is-your-code-for-the-public-good"&gt;
&lt;h2 id="is-your-code-for-the-public-good"&gt;Is your code for the public good?&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;As a community, we take too much for granted: Code hosting, free of charge, is regarded almost as a &lt;i&gt;public utility&lt;/i&gt;.  But in reality, it's far from that: we are relying on untrustworthy companies, assuming they won't tamper with our code and keep their servers up and running forever, free of cost.&lt;/p&gt;
&lt;p&gt;And to top it all off, there's the irony, or should I say &lt;a href="http://mako.cc/writing/hill-free_tools.html" class="external"&gt;&lt;i&gt;hypocrisy&lt;/i&gt;&lt;/a&gt;, of the free software community's dependence on proprietary software for critical project infrastructure. At the same time, some of us are trying to explain to people why proprietary software is &lt;a href="https://www.fsf.org/about/what-is-free-software" class="external"&gt;harmful to society&lt;/a&gt;.  Most people just choose what's most convenient when deciding where to host code.  We need to realise that this decision can be a political, philosophical and ethical choice.  This is my main motivation to move all my personal projects &lt;a href="https://bitbucket.org/sjamaan/" class="external"&gt;away from Bitbucket&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There are basically two ways to achieve code hosting freedom: The first is to entrust your code to a nonprofit organisation which is &lt;i&gt;committed&lt;/i&gt; to supporting free software projects without commercial interference.  For instance, the Free Software Foundation offers &lt;a href="http://savannah.nongnu.org/" class="external"&gt;Savannah&lt;/a&gt;.  There are more specific hosting sites, like those from the &lt;a href="https://wiki.debian.org/Alioth" class="external"&gt;Debian&lt;/a&gt;, &lt;a href="http://incubator.apache.org/" class="external"&gt;Apache&lt;/a&gt;, &lt;a href="https://wiki.gnome.org/Projects/Prerequisites" class="external"&gt;GNOME&lt;/a&gt; and &lt;a href="https://techbase.kde.org/Contribute/Get_a_Contributor_Account" class="external"&gt;KDE&lt;/a&gt; foundations, but they don't accept all projects.  So, for small and personal projects it is probably easier to self-host.&lt;/p&gt;
&lt;p&gt;Now, I know I can't completely avoid proprietary code hosting sites due to the network effect of contributing to free software projects, but for projects I control, I can at least do better.  With CHICKEN we're already &lt;a href="https://code.call-cc.org/" class="external"&gt;hosting our own code&lt;/a&gt; (with mailing lists provided by Savannah).  I decided to host my personal projects on a VPS of my own, which is a good &lt;i&gt;dog fooding&lt;/i&gt; opportunity: I found and fixed a bug in the &lt;a href="http://wiki.call-cc.org/eggref/4/spiffy-cgi-handlers" class="external"&gt;spiffy-cgi-handlers egg&lt;/a&gt; while setting this up.&lt;/p&gt;
&lt;p&gt;The rest of this blog post will explain how I set up &lt;a href="http://code.more-magic.net/" class="external"&gt;code.more-magic.net&lt;/a&gt;.  It's not difficult, so hopefully I can inspire you to consider hosting your own code too.&lt;/p&gt;&lt;a href="#installing-git-cgit-and-chicken"&gt;
&lt;h2 id="installing-git-cgit-and-chicken"&gt;Installing Git, cgit and CHICKEN&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;I knew right away that I didn't need all the bells and whistles that &lt;a href="https://about.gitlab.com/features/" class="external"&gt;GitLab&lt;/a&gt; or &lt;a href="http://phabricator.org/" class="external"&gt;Phabricator&lt;/a&gt; provide.  I just want to host a few small personal projects, and if ever one really did become popular (ha ha), it would make sense to set up a dedicated server like we have for CHICKEN.&lt;/p&gt;
&lt;p&gt;I also decided to convert my Mercurial repositories to Git, to consolidate my VCS usage: At work we're using it, CHICKEN is using it, and so are other projects I contribute to.  I'm tired of context-switching all the time, and I'm finally acclimated to &lt;a href="http://magit.vc/" class="external"&gt;magit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Since I'm only using Git, I don't need to worry about VCS independence of the code hosting tool.  Preferably it shouldn't need much RAM, to keep hosting costs down.  I narrowed it down to &lt;a href="http://git-scm.com/docs/gitweb.html" class="external"&gt;gitweb&lt;/a&gt; or &lt;a href="https://git.zx2c4.com/cgit/" class="external"&gt;cgit&lt;/a&gt;.  I chose the latter because its UI is less messy and confusing than the former (to me, at least).&lt;/p&gt;
&lt;p&gt;Installing cgit is easy as 1, 2, 3:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;$ sudo apt-get install git cgit&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;It is possible to install CHICKEN from &lt;a href="https://packages.debian.org/stable/lisp/chicken-bin" class="external"&gt;its Debian package&lt;/a&gt;, but as a core developer I always want the latest version. Besides, CHICKEN only depends on libc, so it's no big deal:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;$ sudo apt-get install gcc make libc-dev
$ wget https://code.call-cc.org/releases/4.10.0/chicken-4.10.0.tar.gz
$ tar xzf chicken-4.10.0.tar.gz
$ cd chicken-4.10.0&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;By installing it into &lt;tt&gt;/usr/local/chickens/4.10.0&lt;/tt&gt;, you can have multiple versions of CHICKEN installed at the same time:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;$ make PLATFORM=linux PREFIX=/usr/local/chickens/4.10.0
$ sudo make PLATFORM=linux PREFIX=/usr/local/chickens/4.10.0 install&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;A nice trick to help us remember which CHICKEN is being used for Spiffy is to symlink it by usage:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;$ sudo ln -s /usr/local/chickens/4.10.0 /usr/local/chickens/spiffy&lt;/tt&gt;&lt;/pre&gt;&lt;a href="#setting-up-spiffy-under-systemd"&gt;
&lt;h2 id="setting-up-spiffy-under-systemd"&gt;Setting up Spiffy under systemd&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Let's start by installing the &lt;a href="http://wiki.call-cc.org/eggref/4/spiffy" class="external"&gt;Spiffy&lt;/a&gt; egg.  We'll also need a &lt;a href="http://wiki.call-cc.org/eggref/4/spiffy-cgi-handlers" class="external"&gt;CGI handler&lt;/a&gt; to use cgit from Spiffy:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;$ /usr/local/chickens/spiffy/chicken-install -s spiffy spiffy-cgi-handlers&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;First, we must create a small script to run Spiffy.  Put this in &lt;tt&gt;/usr/local/libexec/spiffy.scm&lt;/tt&gt; and make it executable:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;#!/usr/local/chickens/spiffy/bin/csi -s

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;use data-structures spiffy uri-common intarweb cgi-handler&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;spiffy-user &lt;span class="string"&gt;&amp;quot;www-data&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;spiffy-group &lt;span class="string"&gt;&amp;quot;www-data&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;server-port 80&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;root-path &lt;span class="string"&gt;&amp;quot;/usr/share/cgit&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;error-log &lt;span class="string"&gt;&amp;quot;/var/log/spiffy/error.log&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;access-log &lt;span class="string"&gt;&amp;quot;/var/log/spiffy/access.log&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="comment"&gt;;(debug-log &amp;quot;/var/log/spiffy/debug.log&amp;quot;)
&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; cgit &lt;span class="paren2"&gt;(&lt;span class="default"&gt;cgi-handler* &lt;span class="string"&gt;&amp;quot;/usr/lib/cgit/cgit.cgi&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="comment"&gt;;; cgit expects its PATHINFO to contain the full request URI path.
&lt;/span&gt;&lt;span class="comment"&gt;;; However, this is a 404 handler, so we haven&amp;#x27;t resolved the path
&lt;/span&gt;&lt;span class="comment"&gt;;; to a final file.  This means we don&amp;#x27;t know what part of the URI
&lt;/span&gt;&lt;span class="comment"&gt;;; is the &amp;quot;script path&amp;quot; and which is the remainder (the pathinfo).
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;handle-not-found
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;lambda&lt;/span&gt;&lt;/i&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;p&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let*&lt;/span&gt;&lt;/i&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;uri &lt;span class="paren6"&gt;(&lt;span class="default"&gt;request-uri &lt;span class="paren1"&gt;(&lt;span class="default"&gt;current-request&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
           &lt;span class="paren5"&gt;(&lt;span class="default"&gt;uri-path-rest &lt;span class="paren6"&gt;(&lt;span class="default"&gt;cdr &lt;span class="paren1"&gt;(&lt;span class="default"&gt;uri-path uri&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
           &lt;span class="paren5"&gt;(&lt;span class="default"&gt;path &lt;span class="paren6"&gt;(&lt;span class="default"&gt;string-intersperse uri-path-rest &lt;span class="string"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;parameterize &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;span class="paren6"&gt;(&lt;span class="default"&gt;current-pathinfo uri-path-rest&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
        &lt;span class="paren5"&gt;(&lt;span class="default"&gt;cgit path&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="comment"&gt;;; For the root request (otherwise you&amp;#x27;ll get 403 forbidden)
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;handle-directory cgit&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;start-server&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Now, teach logrotate about the log files we configured, by saving this as &lt;tt&gt;/etc/logrotate.d/spiffy&lt;/tt&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;/var/log/spiffy/access.log
/var/log/spiffy/error.log
/var/log/spiffy/debug.log {
    daily
    missingok
    rotate 10
    compress
    delaycompress
    notifempty
    # If you're in the adm group, you can read logs without sudo
    create 640 www-data adm
}&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This rotates logs daily, going back 10 days.  Spiffy won't create the directory, and needs to be able to write to the file as &lt;tt&gt;www-data&lt;/tt&gt;, so let's create the files and the directory:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;$ sudo mkdir /var/log/spiffy
$ sudo touch /var/log/spiffy/{access,error,debug}.log
$ sudo chown -R www-data:adm /var/log/spiffy&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;a href="http://wiki.call-cc.org/spiffy-systemd-scripts" class="external"&gt;systemd script&lt;/a&gt; from our wiki is a bit too complicated, so I based mine on a simpler example from Python's &lt;a href="http://docs.gunicorn.org/en/stable/deploy.html#systemd" class="external"&gt;Gunicorn documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Put the following in &lt;tt&gt;/etc/systemd/system/multi-user.target.wants/spiffy.service&lt;/tt&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;[Unit]
Description=Spiffy the web server
After=network-online.target

[Service]
User=root
Group=www-data
WorkingDirectory=/usr/share/cgit/
ExecStart=/usr/local/libexec/spiffy.scm
ExecStop=/bin/kill -s TERM $MAINPID

[Install]
WantedBy=multi-user.target&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Note that we need to run it as root so that it can bind to port 80. It will drop the privileges itself.  To register this unit file immediately, you'll need to reload systemd:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;$ sudo systemctl daemon-reload&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Now you can start Spiffy simply by typing:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;$ sudo systemctl start spiffy&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;If you visit the website with a browser, you'll notice that the styling doesn't work yet.  To fix that, we'll turn to the cgit configuration.&lt;/p&gt;&lt;a href="#configuring-cgit"&gt;
&lt;h2 id="configuring-cgit"&gt;Configuring cgit&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;The default configuration puts cgit's assets at &lt;tt&gt;/cgit-css&lt;/tt&gt;.  You could set up Spiffy so that this is handled from &lt;tt&gt;/usr/share/cgit&lt;/tt&gt;, but it's much simpler to remove the prefix from the configuration. While we're at it, let's add some Git repositories as well.  Open up &lt;tt&gt;/etc/cgitrc&lt;/tt&gt; and put this in there:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;# cgit config, see cgitrc(5) for details

css=/cgit.css
logo=/cgit.png

repo.url=testrepo1
repo.path=/srv/git/test1
repo.desc=This is my first git test repository

section=A section for repo 2
repo.url=testrepo2
repo.path=/srv/git/test2
repo.desc=This is my second git test repository&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Let's make sure the git repos exist:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;$ sudo mkdir /srv/git
$ sudo chown user:user /srv/git
$ sudo chmod 755 /srv/git
$ git init --bare /srv/git/test1
$ git init --bare /srv/git/test2&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;If you now visit the web site (no reload/restart necessary), you should see a fully functional cgit installation.&lt;/p&gt;&lt;a href="#improving-the-cgit-configuration"&gt;
&lt;h2 id="improving-the-cgit-configuration"&gt;Improving the cgit configuration&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;The above is a simple configuration.  My configuration currently looks more like the following:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;# cgit config, see cgitrc(5) for details

css=/cgit.css
logo=/cgit.png

root-title=My repositories
root-desc=This is my repo browser. There are many like it, but this one is mine.

# This will show a &amp;quot;clone&amp;quot; section at the bottom of each repo.
clone-prefix=http://code.example.com ssh://code.example.com

# If you don't want clones to be made over HTTP, you must disable it!
#enable-http-clone=0

# When you want to serve eggs from cgit, snapshot links are helpful.
# Note that snapshots can be downloaded even when links are not shown!
snapshots=tar.gz

# Show readme files in &amp;quot;about&amp;quot; tab.  The colon tells cgit to take the
# file from the default branch (usually master). IMPORTANT: See below!
readme=:README
readme=:readme
readme=:readme.txt
readme=:README.txt
readme=:readme.md
readme=:README.md

# Process readme files with a file extension-specific formatter.
# Be *very* careful with this!  The default filter allows arbitrary
# HTML which means XSS, cookie hijacking and other tricks, so either
# run this on a sand-boxed domain or be careful who gets commit access.
about-filter=/usr/lib/cgit/filters/about-formatting.sh

# Highlight source files.  This requires the &amp;quot;python-pygments&amp;quot; package.
# For maximum dog fooding, I should use the colorize egg here :)
source-filter=/usr/lib/cgit/filters/syntax-highlighting.py

# Automatically scan /srv/git for repos.  If you want to de-list some,
# simply make them unreadable for the www-data user.  Important: this
# must be the last statement: everything after it is ignored!
section-from-path=1
scan-path=/srv/git&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Many thanks to &lt;a href="https://levlaz.org/installing-cgit-nginx-on-debian-jessie/" class="external"&gt;this guide&lt;/a&gt; for pointing out the paths and configuration settings that cgit uses on Debian.  There are two follow-up posts that are useful too.  There's &lt;a href="https://levlaz.org/using-cgit/" class="external"&gt;one with tips on how to use cgit in practice&lt;/a&gt; and &lt;a href="https://levlaz.org/making-cgit-pretty/" class="external"&gt;one about how to tweak the layout&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now go forth and host your own code!&lt;/p&gt;</content>
    <id>tag:more-magic,2016-03-07:/posts/self-hosting-spiffy-cgit.html</id>
    <published>2016-03-07T19:48:52Z</published>
    <title type="text">Self hosting with cgit using Spiffy</title>
    <updated>2016-03-07T19:48:52Z</updated>
    <link href="https://www.more-magic.net/posts/self-hosting-spiffy-cgit.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;I just &lt;a href="http://lists.gnu.org/archive/html/chicken-hackers/2016-01/msg00002.html" class="external"&gt;submitted a patch&lt;/a&gt; to add a statistical profiler to CHICKEN.  In this post, I'll explain how it works.  It's easier than you'd think!&lt;/p&gt;&lt;a href="#instrumentation-based-profiling"&gt;
&lt;h2 id="instrumentation-based-profiling"&gt;Instrumentation-based profiling&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;There are two major ways to profile a program.  The first way has been supported by CHICKEN as long as I can remember: You add &lt;i&gt;instrumentation&lt;/i&gt; to each procedure.  This counts how often the procedure is called, and how much time is spent in it.&lt;/p&gt;
&lt;p&gt;You've probably done this by hand: You check the clock before and after calling a procedure, and print the difference.  This can be useful when whittling down a specific procedure's run time.  But when you want to know where the bottlenecks are in the first place, it's less practical.  You don't want to manually add this stuff to all your procedures!&lt;/p&gt;
&lt;p&gt;In order to easily instrument each procedure, you'll need language support, either in the compiler or in the run time.  Unfortunately, the instrumentation itself will cause your program to slow down: all this tracking takes some time!  That's why CHICKEN's profiler is part of the compiler: Instrumentation is emitted only when you compile with &lt;tt&gt;-profile&lt;/tt&gt;.  This option adds wrappers around each procedure, which look like this:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="comment"&gt;;; Original source code:
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;foo a b c&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;print &lt;span class="paren3"&gt;(&lt;span class="default"&gt;+ a b&lt;/span&gt;)&lt;/span&gt; c&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="comment"&gt;;; Instrumented version created by -profile:
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; foo
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;lambda&lt;/span&gt;&lt;/i&gt; args
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;dynamic-wind  &lt;span class="comment"&gt;; Explained later
&lt;/span&gt;      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;lambda&lt;/span&gt;&lt;/i&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;##sys#profile-entry 0 profile-info-1234.4567&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;lambda&lt;/span&gt;&lt;/i&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;apply &lt;span class="paren6"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;lambda&lt;/span&gt;&lt;/i&gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;a b c&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;print &lt;span class="paren2"&gt;(&lt;span class="default"&gt;+ a b&lt;/span&gt;)&lt;/span&gt; c&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; args&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;lambda&lt;/span&gt;&lt;/i&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;##sys#profile-exit 0 profile-info-1234.4567&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;In the above code, &lt;tt&gt;##sys#profile-entry&lt;/tt&gt; starts the clock and increments the call count for this procedure, and &lt;tt&gt;##sys#profile-exit&lt;/tt&gt; stops the clock.  The &lt;tt&gt;profile-info-1234.4567&lt;/tt&gt; is a global vector in which each procedure of this compilation unit is assigned a unique position.&lt;/p&gt;
&lt;p&gt;To create the vector and assign the positions, a prelude is added to the compilation unit.  This defines the vector and registers a position for each procedure:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="comment"&gt;;; Prelude for entire program:
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; profile-info-1234.4567 &lt;span class="paren2"&gt;(&lt;span class="default"&gt;##sys#register-profile-info 1 #t&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;##sys#set-profile-info-vector! profile-info-1234.4567 0 &amp;#x27;foo&lt;/span&gt;)&lt;/span&gt;

&lt;span class="comment"&gt;;; Not exactly true, but let&amp;#x27;s pretend because it&amp;#x27;s close enough:
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;on-exit ##sys#finish-profile&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This simply creates a vector of size one, and assigns the &lt;tt&gt;foo&lt;/tt&gt; procedure to position zero.  Then it requests &lt;tt&gt;##sys#finish-profile&lt;/tt&gt; to run when the program exits.  This will write profile information to disk on exit.&lt;/p&gt;&lt;a href="#we-need-dynamic-windbut-it-creates-problems"&gt;
&lt;h3 id="we-need-dynamic-windbut-it-creates-problems"&gt;We need &lt;tt&gt;dynamic-wind&lt;/tt&gt;, but it creates problems&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;If you're not familiar with it, &lt;a href="http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_idx_576" class="external"&gt;dynamic-wind&lt;/a&gt; is a sort of &amp;quot;&lt;tt&gt;guard&lt;/tt&gt;&amp;quot; or &amp;quot;&lt;tt&gt;try&lt;/tt&gt;/&lt;tt&gt;finally&lt;/tt&gt;&amp;quot;.  Whenever the second lambda is entered, the first lambda (&amp;quot;before&amp;quot;) is invoked, and when it is left, the third lambda (&amp;quot;after&amp;quot;) is invoked.  To understand why we need a &lt;tt&gt;dynamic-wind&lt;/tt&gt; in the code presented earlier, consider the naive, incorrect implementation:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="comment"&gt;;; INCORRECT expansion:
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; foo
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;lambda&lt;/span&gt;&lt;/i&gt; args
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;begin
      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;##sys#profile-entry 0 profile-info-1234.4567&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;apply &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;lambda&lt;/span&gt;&lt;/i&gt; &lt;span class="paren6"&gt;(&lt;span class="default"&gt;a b c&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren6"&gt;(&lt;span class="default"&gt;print &lt;span class="paren1"&gt;(&lt;span class="default"&gt;+ a b&lt;/span&gt;)&lt;/span&gt; c&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; args&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="comment"&gt;;; Not reached if + throws an exception.  This
&lt;/span&gt;      &lt;span class="comment"&gt;;; will happen when a or b are not numbers!
&lt;/span&gt;      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;##sys#profile-exit 0 profile-info-1234.4567&lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Here, the &amp;quot;after&amp;quot; part will be skipped if the procedure raises an exception.  Furthermore, a continuation might be captured or called in the procedure, even multiple times.  This would cause the code to jump in and out of the procedure without neatly going over the before/after bits every time. Because of this, the profiler would miss these exits and re-entries, and hence it would not be able to accurately keep track of the time &lt;i&gt;actually&lt;/i&gt; spent in this procedure.&lt;/p&gt;
&lt;p&gt;The code with &lt;tt&gt;dynamic-wind&lt;/tt&gt; will take care of non-local exits, stopping the clock whenever we jump out of the procedure, and starting it when we jump in again via a captured continuation.&lt;/p&gt;
&lt;p&gt;While &lt;tt&gt;dynamic-wind&lt;/tt&gt; is necessary, it also implies quite a heavy hit on performance: &lt;tt&gt;dynamic-wind&lt;/tt&gt; isn't cheap.  Even worse is the fact that it prevents the compiler from inlining small procedures in larger ones.  Furthermore, the use of &lt;tt&gt;apply&lt;/tt&gt; implies we'll need to cons up an argument list.  Normally, arguments aren't put into a Scheme list, because doing so results in more garbage being created.  This means that the performance shape of the profiled application can be quite different from the original, non-profiled application!&lt;/p&gt;&lt;a href="#statistical-profiling"&gt;
&lt;h2 id="statistical-profiling"&gt;Statistical profiling&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;I've always wanted to look into fixing the profiler, but never had the energy to do so.  Now that Felix wrote &lt;a href="http://lists.gnu.org/archive/html/chicken-hackers/2015-11/msg00044.html" class="external"&gt;an entire graphical debugger for CHICKEN&lt;/a&gt;, I thought maybe I could lean on the debugger's infrastructure to make a better profiler. But it turned out I didn't have to!&lt;/p&gt;
&lt;p&gt;First, I should explain statistical profiling.  The basic idea is that the process is periodically &lt;i&gt;sampled&lt;/i&gt; while it's running.  These samples are taken by inspecting the instruction pointer and mapping it to a procedure.  If you do this often enough (every 10 ms or so), you can get a pretty good idea of where the program is spending most of its time.&lt;/p&gt;&lt;a href="#chickens-trace-buffer"&gt;
&lt;h3 id="chickens-trace-buffer"&gt;CHICKEN's trace buffer&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Looking at the instruction pointer or C function is not very useful in CHICKEN, unless you like to pore over endless piles of machine-generated C code and to mentally map it back to Scheme.  It can be educational and even fun, just like it can be fun and educational to read the assembly output of a C compiler, but it is generally unproductive and gets frustrating quickly.&lt;/p&gt;
&lt;p&gt;So how can we take a snapshot of what a Scheme program is doing at any given time?  It turns out that CHICKEN already does this: when a Scheme program raises an exception, the interpreter will show you a &lt;i&gt;call trace&lt;/i&gt;.  This is a bit like a stack trace in a &amp;quot;traditional&amp;quot; language, only it shows a trace of the execution flow that led to the error.  Let's look at a contrived example:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;fib n&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;if&lt;/span&gt;&lt;/i&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&amp;lt; n 2&lt;/span&gt;)&lt;/span&gt;
      n
      &lt;span class="paren3"&gt;(&lt;span class="default"&gt;+ &lt;span class="paren4"&gt;(&lt;span class="default"&gt;fib &lt;span class="paren5"&gt;(&lt;span class="default"&gt;- n 1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;fib &lt;span class="paren5"&gt;(&lt;span class="default"&gt;- n 2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;run-fib&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let*&lt;/span&gt;&lt;/i&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;n &lt;span class="paren5"&gt;(&lt;span class="default"&gt;string-&amp;gt;number &lt;span class="paren6"&gt;(&lt;span class="default"&gt;car &lt;span class="paren1"&gt;(&lt;span class="default"&gt;command-line-arguments&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;result &lt;span class="paren5"&gt;(&lt;span class="default"&gt;fib n&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="comment"&gt;;; This line is wrong: It tries to append a number to a string
&lt;/span&gt;    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;print &lt;span class="paren4"&gt;(&lt;span class="default"&gt;string-append &lt;span class="string"&gt;&amp;quot;Result: &amp;quot;&lt;/span&gt; result&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;run-fib&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;When you compile the program and run it, you'll see the output:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; $ csc -O3 fib.scm
 $ ./fib 3
 
 Error: (string-append) bad argument type - not a string: 2
 
         Call history:
         
         fib.scm:12: run-fib
         fib.scm:7: command-line-arguments
         fib.scm:8: fib
         fib.scm:4: fib
         fib.scm:4: fib
         fib.scm:4: fib
         fib.scm:4: fib
         fib.scm:10: string-append               &amp;lt;--&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;In a &lt;i&gt;stack trace&lt;/i&gt; you would see only two lines, mentioning &lt;tt&gt;run-fib&lt;/tt&gt; and &lt;tt&gt;string-append&lt;/tt&gt;.  Here we can see the trace of execution through the program, where it entered &lt;tt&gt;run-fib&lt;/tt&gt;, then called &lt;tt&gt;command-line-arguments&lt;/tt&gt;, proceeded to invoke &lt;tt&gt;fib&lt;/tt&gt; five times in total, and finally it invoked &lt;tt&gt;string-append&lt;/tt&gt; with the result.&lt;/p&gt;
&lt;p&gt;There are advantages and disadvantages to either approach, but a trace makes more sense in languages with full continuations.  It is the natural thing to do in a compiler that converts all programs to continuation-passing style.  It does tend to confuse beginners, though!&lt;/p&gt;
&lt;p&gt;So, these trace points are already inserted into every program by default.  This happens even in programs optimised with &lt;tt&gt;-O3&lt;/tt&gt;, because trace points have very little overhead: It's just a pointer into a ring buffer that gets updated to point to the procedure's name. You can choose to omit traces completely via &lt;tt&gt;-no-trace&lt;/tt&gt; or &lt;tt&gt;-d0&lt;/tt&gt;, but that's not the default.&lt;/p&gt;
&lt;p&gt;Trace points are a good fit for our profiler: when taking a sample, we can simply take a look at the newest entry in the trace buffer, which will always reflect the procedure that's currently running!&lt;/p&gt;&lt;a href="#setting-up-a-sampler"&gt;
&lt;h3 id="setting-up-a-sampler"&gt;Setting up a sampler&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;So how can we interrupt the program at a point in time, without messing with the program's state?  This is simple: we ask for a signal to be delivered periodically.  There's even a dedicated signal reserved for this very task: &lt;tt&gt;SIGPROF&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;We'll use &lt;a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/setitimer.html" class="external"&gt;setitimer()&lt;/a&gt; to set up the timer which causes the signal to be delivered, even though POSIX says it's obsolete.  It is much more convenient and more widely supported than the alternative, &lt;a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_create.html" class="external"&gt;timer_create()&lt;/a&gt; plus &lt;a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_settime.html" class="external"&gt;timer_settime()&lt;/a&gt;. We can always switch when &lt;tt&gt;setitimer()&lt;/tt&gt; is removed from an actual POSIX implementation.&lt;/p&gt;
&lt;p&gt;The following setup code is simplified a bit (most importantly, error handling is omitted):&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;C_word CHICKEN_run&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;span class="symbol"&gt;void&lt;/span&gt; *toplevel&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt; &lt;span class="comment"&gt;/* Initialisation code for CHICKEN */&lt;/span&gt;
  &lt;span class="comment"&gt;/* ... a lot more code ... */&lt;/span&gt;

  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;profiling&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    &lt;span class="symbol"&gt;struct&lt;/span&gt; itimerval itv;
    time_t freq = 10000;                   &lt;span class="comment"&gt;/* 10 msec (in usec) */&lt;/span&gt;

    itv.it_value.tv_sec = freq / 1000000;
    itv.it_value.tv_usec = freq % 1000000;
    itv.it_interval.tv_sec = itv.it_value.tv_sec;
    itv.it_interval.tv_usec = itv.it_value.tv_usec;

    setitimer&lt;span class="paren3"&gt;(&lt;span class="default"&gt;ITIMER_PROF, &amp;amp;itv, NULL&lt;/span&gt;)&lt;/span&gt;;
    signal&lt;span class="paren3"&gt;(&lt;span class="default"&gt;SIGPROF, profile_signal_handler&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt;

  &lt;span class="comment"&gt;/* ... a lot more code ... */&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This sets up a profile timer.  When such a timer expires, the kernel will send &lt;tt&gt;SIGPROF&lt;/tt&gt; to the process.  The code also registers a signal handler that will be invoked when this happens.  It looks like this, much simplified:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="symbol"&gt;struct&lt;/span&gt; profile_item           &lt;span class="comment"&gt;/* Item in our profiling hash table */&lt;/span&gt;
&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  &lt;span class="symbol"&gt;char&lt;/span&gt; *key;                  &lt;span class="comment"&gt;/* Procedure name, taken from trace buffer */&lt;/span&gt;
  &lt;span class="symbol"&gt;unsigned&lt;/span&gt; &lt;span class="symbol"&gt;int&lt;/span&gt; sample_count;  &lt;span class="comment"&gt;/* Times this procedure was seen */&lt;/span&gt;
  &lt;span class="symbol"&gt;struct&lt;/span&gt; profile_item *next;  &lt;span class="comment"&gt;/* Next bucket chain */&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;;

&lt;span class="symbol"&gt;void&lt;/span&gt; profile_signal_handler&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;span class="symbol"&gt;int&lt;/span&gt; signum&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  &lt;span class="symbol"&gt;struct&lt;/span&gt; profile_item *pi;
  &lt;span class="symbol"&gt;char&lt;/span&gt; *procedure_name;

  procedure_name = get_topmost_trace_entry&lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt;;

  pi = profile_table_lookup&lt;span class="paren2"&gt;(&lt;span class="default"&gt;procedure_name&lt;/span&gt;)&lt;/span&gt;;

  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;pi == NULL&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    pi = profile_table_insert&lt;span class="paren3"&gt;(&lt;span class="default"&gt;procedure_name&lt;/span&gt;)&lt;/span&gt;;
    pi-&amp;gt;sample_count = 1;
  &lt;/span&gt;}&lt;/span&gt; &lt;span class="symbol"&gt;else&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    pi-&amp;gt;sample_count++;
  &lt;/span&gt;}&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Maybe you are wondering why we're doing this in C rather than Scheme. After all, Scheme code is more readable and easier to maintain.  There are a few reasons for that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scheme signal handlers are blocked in some critical sections of the run time library.  This would delay profiling until the program is back in user code, skewing the results.&lt;/li&gt;
&lt;li&gt;Core is compiled with &lt;tt&gt;-no-trace&lt;/tt&gt; by default, but this can be turned off.  Doing so can be useful when profiling core procedures, but not with a signal handler in Scheme.  It would see &lt;i&gt;its own code&lt;/i&gt; in the trace buffer, instead of what we want to trace!&lt;/li&gt;
&lt;li&gt;The profiling code should be as low-overhead as possible, to avoid affecting the results.  Remember, this is one of the main problems with the instrumenting profiler!  While CHICKEN produces fast code, it is faster if we do it directly in C, and it will trigger no garbage collections.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;After the program has completed its run, we must write the profile to a file. I won't show it here, but the CHICKEN implementation simply writes each key in the hash table with its call count and the time spent in that procedure.  The time is &lt;i&gt;estimated&lt;/i&gt; by multiplying the sampling frequency by the call count.&lt;/p&gt;
&lt;p&gt;This means we'll miss some calls, and therefore we'll under-represent the time taken by those procedures.  On the other hand, some procedures are over-represented: if a sample is taken for a very fast procedure, we'll assign 10ms to it, even if it runs in a fraction of that.  This is the essence of the statistical approach: if a program runs long enough, these measurement errors should balance out.&lt;/p&gt;&lt;a href="#comparing-the-two-profilers"&gt;
&lt;h2 id="comparing-the-two-profilers"&gt;Comparing the two profilers&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;It's hard to come up with a small but representative example which is self-contained, so I'll use a few benchmarks from &lt;a href="https://github.com/mario-goulart/chicken-benchmarks" class="external"&gt;Mario's collection&lt;/a&gt;.&lt;/p&gt;&lt;a href="#low-level-vs-high-level"&gt;
&lt;h3 id="low-level-vs-high-level"&gt;Low-level vs high-level&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;The first benchmark we'll profile is the &lt;a href="https://raw.githubusercontent.com/mario-goulart/chicken-benchmarks/master/progs/kernwyk-array.scm" class="external"&gt;kernwyk-array&lt;/a&gt; benchmark.  It's taken from &lt;a href="http://www.ccs.neu.edu/home/will/Twobit/KVW/kvwbenchmarks.html" class="external"&gt;a historical set of benchmarks by Kernighan and Van Wyk&lt;/a&gt;, designed to compare the performance of various &amp;quot;scripting languages&amp;quot;.  This particular benchmark creates an array containing a million numbers by destructively initialising it.  After that, it creates a second array into which the first is copied.  This is repeated 100 times.&lt;/p&gt;
&lt;p&gt;If we compile this with &lt;tt&gt;csc -O3 -profile&lt;/tt&gt; and run it, the original profiler gives us the following breakdown:&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;procedure&lt;/th&gt;
&lt;th&gt;calls&lt;/th&gt;
&lt;th&gt;seconds&lt;/th&gt;
&lt;th&gt;average&lt;/th&gt;
&lt;th&gt;percent&lt;/th&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;my-try&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;4.008&lt;/td&gt;
&lt;td&gt;0.040&lt;/td&gt;
&lt;td&gt;100.000&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;go&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;4.008&lt;/td&gt;
&lt;td&gt;4.008&lt;/td&gt;
&lt;td&gt;100.000&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;create-y&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;2.311&lt;/td&gt;
&lt;td&gt;0.023&lt;/td&gt;
&lt;td&gt;57.684&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;create-x&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;1.696&lt;/td&gt;
&lt;td&gt;0.016&lt;/td&gt;
&lt;td&gt;42.315&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;If we compile this with &lt;tt&gt;csc -O3&lt;/tt&gt; and run it with &lt;tt&gt;-:p&lt;/tt&gt; under the new profiler, we'll get a radically different result, even though the total run time did not change much:&lt;/p&gt;
&lt;table&gt;
&lt;table&gt;

&lt;tr&gt;
&lt;th&gt;procedure&lt;/th&gt;
&lt;th&gt;calls&lt;/th&gt;
&lt;th&gt;seconds&lt;/th&gt;
&lt;th&gt;average&lt;/th&gt;
&lt;th&gt;percent&lt;/th&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;kernwyk-array.scm:12:make-vector&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;2.400&lt;/td&gt;
&lt;td&gt;0.024&lt;/td&gt;
&lt;td&gt;58.679&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;kernwyk-array.scm:5:make-vector&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;1.690&lt;/td&gt;
&lt;td&gt;0.016&lt;/td&gt;
&lt;td&gt;41.320&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/table&gt;
&lt;p&gt;The statistical profiler is a bit more &amp;quot;low-level&amp;quot;: It tells you exactly the procedure call and line that is taking the most time.  On the other hand, the instrumentation-based profiler shows us a breakdown in which procedure the most time is spent.  The percentages and &amp;quot;seconds&amp;quot; column are also different: the original profiler shows us the cumulative time each procedure takes up.  Thus, a main entry point will always be at 100% at the top.&lt;/p&gt;
&lt;p&gt;But the most significant difference is in what this tells us about where the time is spent: the original profiler tells us that &lt;tt&gt;create-y&lt;/tt&gt; is a little slower than &lt;tt&gt;create-x&lt;/tt&gt;.  Reading such output would lead me to think that probably &lt;tt&gt;vector-ref&lt;/tt&gt; and &lt;tt&gt;vector-set!&lt;/tt&gt; take the most time.  If we remove all calls to those, the program takes &lt;tt&gt;2.6&lt;/tt&gt; seconds, and the profiler output looks more or less the same, so they're not the biggest contributor to the total run time.  Instead, &lt;tt&gt;make-vector&lt;/tt&gt; is, due to the fact that it allocates, which will cause garbage collections.  And garbage collections are the real time consumers in this benchmark!&lt;/p&gt;&lt;a href="#precision-of-the-two-profilers"&gt;
&lt;h3 id="precision-of-the-two-profilers"&gt;Precision of the two profilers&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;The next benchmark we'll look at is the &lt;a href="https://raw.githubusercontent.com/mario-goulart/chicken-benchmarks/master/progs/nfa.scm" class="external"&gt;nfa benchmark&lt;/a&gt;.  I'm not sure about the origins of this benchmark.  It emulates a depth-first NFA search for the regular expression &lt;tt&gt;((a | c)* b c d) | (a* b c)&lt;/tt&gt;.  This is matched against a string containing 133 &amp;quot;&lt;tt&gt;a&lt;/tt&gt;&amp;quot; characters followed by &amp;quot;&lt;tt&gt;bc&lt;/tt&gt;&amp;quot;.&lt;/p&gt;
&lt;p&gt;The output of the instrumenting profiler is completely useless, because only toplevel procedures are instrumented:&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;procedure&lt;/th&gt;
&lt;th&gt;calls&lt;/th&gt;
&lt;th&gt;seconds&lt;/th&gt;
&lt;th&gt;average&lt;/th&gt;
&lt;th&gt;percent&lt;/th&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;recursive-nfa&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;150000&lt;/td&gt;
&lt;td&gt;8.071&lt;/td&gt;
&lt;td&gt;0.000&lt;/td&gt;
&lt;td&gt;100.000&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;This is another reason for wanting to &amp;quot;fix&amp;quot; the profiler: it doesn't give an inside view of where large procedures or closures are spending their time.  You can manually tweak the programs by lifting all the inner procedures up to the toplevel.  If these procedures close over some variables, you must turn those into extra arguments and pass them along when calling these procedures.  It's a bit tedious, but if we do this for the benchmark, we'll get output that is more useful:&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;procedure&lt;/th&gt;
&lt;th&gt;calls&lt;/th&gt;
&lt;th&gt;seconds&lt;/th&gt;
&lt;th&gt;average&lt;/th&gt;
&lt;th&gt;percent&lt;/th&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;recursive-nfa&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;150000&lt;/td&gt;
&lt;td&gt;30.687&lt;/td&gt;
&lt;td&gt;0.00020458&lt;/td&gt;
&lt;td&gt;100.000&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;state0&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;150000&lt;/td&gt;
&lt;td&gt;30.559&lt;/td&gt;
&lt;td&gt;0.00020373&lt;/td&gt;
&lt;td&gt;99.582&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;state1&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;20100000&lt;/td&gt;
&lt;td&gt;23.372&lt;/td&gt;
&lt;td&gt;0.00000116&lt;/td&gt;
&lt;td&gt;76.160&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;state2&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;20100000&lt;/td&gt;
&lt;td&gt;8.423&lt;/td&gt;
&lt;td&gt;0.00000041&lt;/td&gt;
&lt;td&gt;27.450&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;state3&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;20100000&lt;/td&gt;
&lt;td&gt;7.080&lt;/td&gt;
&lt;td&gt;0.00000035&lt;/td&gt;
&lt;td&gt;23.070&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;state4&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;150000&lt;/td&gt;
&lt;td&gt;0.132&lt;/td&gt;
&lt;td&gt;0.00000088&lt;/td&gt;
&lt;td&gt;0.430&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Now, if we take the &lt;i&gt;original, untweaked program&lt;/i&gt;, and run it through the statistical profiler, we'll immediately get useful output:&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;procedure&lt;/th&gt;
&lt;th&gt;calls&lt;/th&gt;
&lt;th&gt;seconds&lt;/th&gt;
&lt;th&gt;average&lt;/th&gt;
&lt;th&gt;percent&lt;/th&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;nfa.scm:14:state1&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;146&lt;/td&gt;
&lt;td&gt;5.830&lt;/td&gt;
&lt;td&gt;0.039&lt;/td&gt;
&lt;td&gt;72.602&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;nfa.scm:31:state3&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;141&lt;/td&gt;
&lt;td&gt;2.160&lt;/td&gt;
&lt;td&gt;0.015&lt;/td&gt;
&lt;td&gt;26.899&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;nfa.scm:9:state1&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0.020&lt;/td&gt;
&lt;td&gt;0.010&lt;/td&gt;
&lt;td&gt;0.249&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;nfa.scm:44:##sys#display-times&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0.010&lt;/td&gt;
&lt;td&gt;0.010&lt;/td&gt;
&lt;td&gt;0.124&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;nfa.scm:9:state3&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0.010&lt;/td&gt;
&lt;td&gt;0.010&lt;/td&gt;
&lt;td&gt;0.124&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;This also shows a &lt;i&gt;dis&lt;/i&gt;advantage of the statistical profiler: the call counts are all wrong!  That's because the state procedures are &lt;i&gt;extremely&lt;/i&gt; fast: in the original profiler you can see that they run 20 million times in 8 seconds or so.  Because they're so fast, the average time per call is close to zero.  This results in the timer being too slow for sampling each procedure while it is running.  It's so slow we only see an extremely small fraction of all calls!&lt;/p&gt;
&lt;p&gt;Nevertheless, we can clearly tell that most time is spent in &lt;tt&gt;state1&lt;/tt&gt; and &lt;tt&gt;state3&lt;/tt&gt;.  The calls for &lt;tt&gt;state2&lt;/tt&gt; are not even registering, because this state will return much sooner: there are almost no &lt;tt&gt;b&lt;/tt&gt;, &lt;tt&gt;c&lt;/tt&gt; or &lt;tt&gt;d&lt;/tt&gt; characters in the input pattern, so it will just quickly &amp;quot;fall through&amp;quot; this procedure without a match.  The reason it shows up in the original profiler is because the instrumentation itself is interfering with an accurate reading of time spent in the procedure.&lt;/p&gt;
&lt;p&gt;The total run time of the instrumented and tweaked version is almost 31 seconds, while the total run time of the version with statistical profiling is less than 8 seconds on my laptop!  Let's take a closer look at that overhead.&lt;/p&gt;&lt;a href="#instrumentation-overhead"&gt;
&lt;h3 id="instrumentation-overhead"&gt;Instrumentation overhead&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Having two distinct ways of gathering profile data opens up a really cool opportunity.  We can measure the overhead introduced by the instrumentation profiler, by running it under the statistical profiler!&lt;/p&gt;
&lt;p&gt;Let's do that on the &amp;quot;tweaked&amp;quot; NFA benchmark again:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; $ csc -O3 -profile nfa.scm
 $ ./nfa -:p
 30.88s CPU time, 2.404s GC time (major),
 163050000/149475510 mutations (total/tracked),
 5972/113664 GCs (major/minor)&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;And let's look at the result:&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;procedure&lt;/th&gt;
&lt;th&gt;calls&lt;/th&gt;
&lt;th&gt;seconds&lt;/th&gt;
&lt;th&gt;average&lt;/th&gt;
&lt;th&gt;percent&lt;/th&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;##sys#profile-entry&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;701&lt;/td&gt;
&lt;td&gt;17.000&lt;/td&gt;
&lt;td&gt;0.024&lt;/td&gt;
&lt;td&gt;55.051&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;##sys#profile-exit&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;633&lt;/td&gt;
&lt;td&gt;10.710&lt;/td&gt;
&lt;td&gt;0.016&lt;/td&gt;
&lt;td&gt;34.682&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;##sys#dynamic-wind&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;145&lt;/td&gt;
&lt;td&gt;1.660&lt;/td&gt;
&lt;td&gt;0.011&lt;/td&gt;
&lt;td&gt;5.375&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;nfa.scm:15:state2&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;61&lt;/td&gt;
&lt;td&gt;0.670&lt;/td&gt;
&lt;td&gt;0.010&lt;/td&gt;
&lt;td&gt;2.169&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;nfa.scm:29:state3&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;41&lt;/td&gt;
&lt;td&gt;0.440&lt;/td&gt;
&lt;td&gt;0.010&lt;/td&gt;
&lt;td&gt;1.424&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;nfa.scm:12:state1&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;31&lt;/td&gt;
&lt;td&gt;0.340&lt;/td&gt;
&lt;td&gt;0.010&lt;/td&gt;
&lt;td&gt;1.101&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;nfa.scm:41:state0&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;0.040&lt;/td&gt;
&lt;td&gt;0.013&lt;/td&gt;
&lt;td&gt;0.129&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;tt&gt;nfa.scm:49:recursive-nfa&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0.020&lt;/td&gt;
&lt;td&gt;0.010&lt;/td&gt;
&lt;td&gt;0.064&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;This clearly shows that the instrumentation machinery completely dominates the profile: A stunning 27 seconds are being soaked up by &lt;tt&gt;##sys#profile-entry&lt;/tt&gt; and &lt;tt&gt;##sys#profile-exit&lt;/tt&gt;!&lt;/p&gt;
&lt;p&gt;Of course, this is just a contrived example of profiling a benchmark. An experienced Chickeneer would have been able to just tell from the output of the benchmark with and without profiling:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; $ csc -O3 nfa.scm
 $ ./nfa
 8.156s CPU time, 0.012s GC time (major), 32/6849 GCs (major/minor)
 $ csc -O3 -profile nfa.scm
 $ ./nfa
 30.628s CPU time, 2.316s GC time (major),
 163050000/149475510 mutations (total/tracked),
 5970/113666 GCs (major/minor)&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Aside from the obvious increase in CPU time, you can see that the number of mutations went from zero to more than a hundred million. The number of garbage collections is also many times higher.  This would spell certain doom if you saw it in a real program!&lt;/p&gt;&lt;a href="#conclusion"&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;It's too early to be sure, but it looks like a statistical profiler is a useful alternative to instrumentation.  On the other hand, for some programs the situation is reversed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Programs blocking &lt;tt&gt;SIGPROF&lt;/tt&gt; offer fewer sampling opportunities, resulting in incomplete profiles.&lt;/li&gt;
&lt;li&gt;If you need the exact number of procedure calls, instrumentation is your only real option.&lt;/li&gt;
&lt;li&gt;When there are lots of smallish procedures called by a few toplevel procedures, the noisy low-level output of the statistical profiler can drown out the useful information.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;I think if we can push down the performance bottleneck caused by the instrumentation, it'll become a lot more useful again.  This won't be easy, because some of the overhead is fundamental to its use of &lt;tt&gt;dynamic-wind&lt;/tt&gt; and the way inlining is prevented by it.  In the mean time, please test the statistical profiler and let me know how it works for you!&lt;/p&gt;</content>
    <id>tag:more-magic,2016-01-04:/posts/statistical-profiling.html</id>
    <published>2016-01-04T19:14:26Z</published>
    <title type="text">Let's add a statistical profiler to CHICKEN!</title>
    <updated>2016-01-04T19:14:26Z</updated>
    <link href="https://www.more-magic.net/posts/statistical-profiling.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;Maybe you've noticed the little &lt;a href="https://flattr.com" class="external"&gt;Flattr&lt;/a&gt; icons that I've added at the bottom of each post, and now you're wondering if, and why, you should support my blogging efforts with a donation.&lt;/p&gt;
&lt;p&gt;Let me state this first and foremost: I enjoy writing posts about subjects that interest me and I learn a lot from the research I put into my posts.  So, even without donations I'd continue doing so. But, it's also a fact that many of my posts demand a lot of effort. Researching, writing and illustrating an in-depth post can take &lt;i&gt;weeks&lt;/i&gt;, depending on my energy levels and other activities.&lt;/p&gt;
&lt;p&gt;I hope you now understand why this blog is updated so slowly.  I'm convinced that few updates with informative, long posts is better than frequent 100-word status updates of my projects.  That would be a waste of your time! But because it takes so much time and effort, sometimes I struggle to find the motivation for writing new posts.&lt;/p&gt;
&lt;p&gt;This is where Flattr comes in: a small donation is a wonderful way to express how much you liked a post, and it can really lift my spirits and motivate me to write more!&lt;/p&gt;
&lt;p&gt;As an added advantage, by seeing which posts get Flattr'd the most I can get a better idea of what you, the readership of my blog, like and what you don't like.  This will help me choose which topics to write about more.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; You can now also donate via Bitcoin, as several people indicated that they wouldn't like to sign up to Flattr.  The bitcoin address you can use is &lt;tt&gt;19uPJ7BVcJea4iFtUiMcFGTEJG8pEbFmDC&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update 2:&lt;/b&gt; After more than 3 years I got only a handful of donations, so I decided to get rid of these buttons.  I've learned from this experiment that (in general) people aren't interested in tipping random strangers for good articles.  Don't worry, I still won't put ads on my blog :)&lt;/p&gt;&lt;a href="#why-i-refuse-to-put-ads-on-my-blog"&gt;
&lt;h3 id="why-i-refuse-to-put-ads-on-my-blog"&gt;Why I refuse to put ads on my blog&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Of course, I know that placing ads on my blog would be the easiest way to get some returns from the hard work that I put into my posts.  This would easily repay my hosting costs.  However, in my opinion, the advertising industry is the most toxic influence on the web today.  It is completely absurd that it's considered normal for companies (and individuals with blogs...) to be &lt;i&gt;rewarded&lt;/i&gt; for filling up our screens with obnoxious garbage, and for eroding our privacy through various tracking mechanisms.  They don't care that all this digital pollution is only going to be acted on by a tiny fraction of all visitors (if any).  It is downright disrespectful; personally I think it's as bad as spam e-mail.&lt;/p&gt;
&lt;p&gt;In my opinion, Flattr is a much more benign way of receiving money for my efforts.  The company was created by a founder of The Pirate Bay, as &lt;a href="http://news.bbc.co.uk/2/hi/technology/8512263.stm" class="external"&gt;a better and more direct alternative&lt;/a&gt; for rewarding creators than the commercial exploitation of copyright law by middle men.  It's also non-unobtrusive: just a small icon in each post.  The integration that I'm using is a simple hyperlink, so no nasty tracking cookies or web beacons; I'm even hosting the icon image myself.&lt;/p&gt;
&lt;p&gt;Besides that, Flattr is completely voluntary on the visitor's part. This means that any rewards are &lt;i&gt;directly&lt;/i&gt; linked to people's enjoyment of my posts.  This encourages informative posts of &lt;i&gt;substance&lt;/i&gt; rather than click-bait titles with disappointing content which would draw more traffic, just to get more ad impressions.&lt;/p&gt;
&lt;p&gt;These are my views on the matter.  If you're using ads on &lt;i&gt;your&lt;/i&gt; blog, I hope I've managed to convince you to switch away from ads to visitor-supported donations.  And if you like my posts, I hope you'll consider making a small donation.&lt;/p&gt;&lt;a href="#integrating-flattr-into-hyde"&gt;
&lt;h3 id="integrating-flattr-into-hyde"&gt;Integrating Flattr into Hyde&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;To make this post at least a little bit on-topic, I'd like to share how I added the Flattr button to my &lt;a href="http://wiki.call-cc.org/eggref/4/hyde" class="external"&gt;Hyde&lt;/a&gt; configuration.  I added the following definition to &lt;tt&gt;hyde.scm&lt;/tt&gt; (slightly modified):&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;use hyde uri-common&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;flattr-button #!optional &lt;span class="paren3"&gt;(&lt;span class="default"&gt;page &lt;span class="paren4"&gt;(&lt;span class="default"&gt;current-page&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let*&lt;/span&gt;&lt;/i&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;base-uri &lt;span class="paren5"&gt;(&lt;span class="default"&gt;uri-reference &lt;span class="string"&gt;&amp;quot;https://flattr.com/submit/auto&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;attrs `&lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;span class="paren6"&gt;(&lt;span class="default"&gt;user_id . &lt;span class="string"&gt;&amp;quot;YOUR FLATTR ACCOUNT NAME&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                  &lt;span class="comment"&gt;;; A bit ugly, but Hyde does it like this, too
&lt;/span&gt;                  &lt;span class="paren6"&gt;(&lt;span class="default"&gt;url . ,&lt;span class="paren1"&gt;(&lt;span class="default"&gt;string-append &lt;span class="paren2"&gt;(&lt;span class="default"&gt;$ &amp;#x27;base-uri page&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;page-path page&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                  &lt;span class="paren6"&gt;(&lt;span class="default"&gt;category . &lt;span class="string"&gt;&amp;quot;text&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                  &lt;span class="paren6"&gt;(&lt;span class="default"&gt;language . ,&lt;span class="paren1"&gt;(&lt;span class="default"&gt;or &lt;span class="paren2"&gt;(&lt;span class="default"&gt;$ &amp;#x27;lang page&lt;/span&gt;)&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;en_GB&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                  &lt;span class="paren6"&gt;(&lt;span class="default"&gt;title . ,&lt;span class="paren1"&gt;(&lt;span class="default"&gt;$ &amp;#x27;title page&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="comment"&gt;;; Flattr doesn&amp;#x27;t grok semicolon as query param separator...
&lt;/span&gt;         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;flattr-page-uri
          &lt;span class="paren5"&gt;(&lt;span class="default"&gt;parameterize &lt;span class="paren6"&gt;(&lt;span class="default"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;form-urlencoded-separator &lt;span class="string"&gt;&amp;quot;&amp;amp;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
            &lt;span class="paren6"&gt;(&lt;span class="default"&gt;uri-&amp;gt;string &lt;span class="paren1"&gt;(&lt;span class="default"&gt;update-uri base-uri &lt;span class="keyword"&gt;query:&lt;/span&gt; attrs&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

    `&lt;span class="paren3"&gt;(&lt;span class="default"&gt;a &lt;span class="paren4"&gt;(&lt;span class="default"&gt;@ &lt;span class="paren5"&gt;(&lt;span class="default"&gt;class &lt;span class="string"&gt;&amp;quot;flattr-button&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
           &lt;span class="paren5"&gt;(&lt;span class="default"&gt;href ,flattr-page-uri&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
        &lt;span class="paren4"&gt;(&lt;span class="default"&gt;img &lt;span class="paren5"&gt;(&lt;span class="default"&gt;@ &lt;span class="paren6"&gt;(&lt;span class="default"&gt;src &lt;span class="string"&gt;&amp;quot;/pics/flattr-button.svg&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                &lt;span class="paren6"&gt;(&lt;span class="default"&gt;alt &lt;span class="string"&gt;&amp;quot;Flattr this!&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                &lt;span class="paren6"&gt;(&lt;span class="default"&gt;title &lt;span class="string"&gt;&amp;quot;Flattr this post!&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Then, in my SXML definition for article layouts which I call, surprise, surprise! &lt;tt&gt;article.sxml&lt;/tt&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="comment"&gt;;; -*- Scheme -*-
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt;

`&lt;span class="paren1"&gt;(&lt;span class="default"&gt;div &lt;span class="paren2"&gt;(&lt;span class="default"&gt;@ &lt;span class="paren3"&gt;(&lt;span class="default"&gt;class &lt;span class="string"&gt;&amp;quot;article&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

        ,@&lt;span class="paren2"&gt;(&lt;span class="default"&gt;prev/next-navigation&lt;/span&gt;)&lt;/span&gt;

        &lt;span class="paren2"&gt;(&lt;span class="default"&gt;h1 &lt;span class="paren3"&gt;(&lt;span class="default"&gt;@ &lt;span class="paren4"&gt;(&lt;span class="default"&gt;class &lt;span class="string"&gt;&amp;quot;article-title&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
            ,&lt;span class="paren3"&gt;(&lt;span class="default"&gt;$ &amp;#x27;title&lt;/span&gt;)&lt;/span&gt; &lt;span class="string"&gt;&amp;quot; &amp;quot;&lt;/span&gt;
            &lt;span class="paren3"&gt;(&lt;span class="default"&gt;small &lt;span class="paren4"&gt;(&lt;span class="default"&gt;@ &lt;span class="paren5"&gt;(&lt;span class="default"&gt;class &lt;span class="string"&gt;&amp;quot;date&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                   &lt;span class="string"&gt;&amp;quot;Posted on &amp;quot;&lt;/span&gt; ,&lt;span class="paren4"&gt;(&lt;span class="default"&gt;format-seconds &lt;span class="paren5"&gt;(&lt;span class="default"&gt;page-updated&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

        &lt;span class="paren2"&gt;(&lt;span class="default"&gt;div &lt;span class="paren3"&gt;(&lt;span class="default"&gt;@ &lt;span class="paren4"&gt;(&lt;span class="default"&gt;class &lt;span class="string"&gt;&amp;quot;article-body&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
             &lt;span class="paren3"&gt;(&lt;span class="default"&gt;inject ,contents&lt;/span&gt;)&lt;/span&gt;
             ,&lt;span class="paren3"&gt;(&lt;span class="default"&gt;flattr-button&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

        ,@&lt;span class="paren2"&gt;(&lt;span class="default"&gt;prev/next-navigation&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The button immediately follows the contents of the blog post, which makes sense because only &lt;i&gt;after&lt;/i&gt; reading a blog post, you'll know whether it was worth something to you.&lt;/p&gt;</content>
    <id>tag:more-magic,2015-10-25:/posts/the-flattr-experiment.html</id>
    <published>2015-10-25T18:35:04Z</published>
    <title type="text">The Flattr "experiment"</title>
    <updated>2015-10-25T18:35:04Z</updated>
    <link href="https://www.more-magic.net/posts/the-flattr-experiment.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;In my &lt;a href="/posts/internals-gc.html" class="internal"&gt;earlier post&lt;/a&gt; about the garbage collector, I lied a little bit about the data representation that CHICKEN uses. At the end of the post I briefly mentioned how CHICKEN really stores objects.  If you want to fully understand the way CHICKEN works, it is important to have a good grasp on how it stores data internally.&lt;/p&gt;&lt;a href="#basic-idea"&gt;
&lt;h2 id="basic-idea"&gt;Basic idea&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;CHICKEN attempts to store data in the most &amp;quot;native&amp;quot; way it can.  Even though it's written in C, it tries hard to use machine words everywhere.  So on a 32-bit machine, the native code that's eventually generated will use 32-bit wide integers and pointers.  On a 64-bit machine it will use 64-bit wide integers and pointers.&lt;/p&gt;
&lt;p&gt;This is known as a &lt;tt&gt;C_word&lt;/tt&gt;, which is usually defined as an &lt;tt&gt;int&lt;/tt&gt; or a &lt;tt&gt;long&lt;/tt&gt;, depending on the platform.  By the way, the &lt;tt&gt;C_&lt;/tt&gt; prefix stands for CHICKEN, not the C language.  Every Scheme value is represented as a &lt;tt&gt;C_word&lt;/tt&gt; internally.  To understand how this can work, you need to know that there are roughly two kinds of objects.&lt;/p&gt;&lt;a href="#immediate-values"&gt;
&lt;h3 id="immediate-values"&gt;Immediate values&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;First, there are the &lt;i&gt;immediate values&lt;/i&gt;.  These are the typical &amp;quot;atomic&amp;quot; values that come up a lot in computations.  It is important to represent these as efficiently as possible, so they are packed directly in a &lt;tt&gt;C_word&lt;/tt&gt;.  This includes booleans, the empty list, small integers (these are called &lt;i&gt;fixnums&lt;/i&gt;), characters and a few other special values.&lt;/p&gt;
&lt;p&gt;Because these values are represented directly by a &lt;tt&gt;C_word&lt;/tt&gt;, they can be compared in one instruction: &lt;tt&gt;eq?&lt;/tt&gt; in Scheme.  These values do not need to be heap-allocated: they fit directly in a register, and can be passed around &amp;quot;by value&amp;quot; in C.  This also means they don't need to be tracked by the garbage collector!&lt;/p&gt;
&lt;p&gt;At a high enough level, these values simply look like this:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/immediate-objects.svg" /&gt;&lt;/p&gt;
&lt;p&gt;This doesn't really show anything, does it?  Well, bear with me...&lt;/p&gt;&lt;a href="#block-objects"&gt;
&lt;h3 id="block-objects"&gt;Block objects&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;The other kind of value is the &lt;i&gt;block object&lt;/i&gt;.  This is a value that is represented as a pointer to a structure that contains a &lt;b&gt;header&lt;/b&gt; and a variable-length &lt;b&gt;data block&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;The data block is a pointer which can conceptually be one of two types.  In case of a string or &lt;a href="http://srfi.schemers.org/srfi-4/srfi-4.html" class="external"&gt;srfi-4&lt;/a&gt; object, the data block is simply an opaque &amp;quot;blob&amp;quot; or byte-vector.  In most other cases, the block is a compound value consisting of other Scheme objects.  Typical examples are pairs, vectors and records.&lt;/p&gt;
&lt;p&gt;Because these values are heap-allocated, two distinct objects are not stored at the same memory address, even if they store the same value. That's why comparing their values is a complex operation.  This operation is either &lt;tt&gt;equal?&lt;/tt&gt; for deep structural comparison, or &lt;tt&gt;eqv?&lt;/tt&gt; for value comparisons of numbers and symbols.&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.1" class="external"&gt;R5RS specification&lt;/a&gt; explains that the difference between &lt;tt&gt;eq?&lt;/tt&gt; and &lt;tt&gt;eqv?&lt;/tt&gt; is not necessarily the same across Scheme implementations. For example, in CHICKEN, &lt;tt&gt;eq?&lt;/tt&gt; can be used to compare characters and fixnums, because they are stored as immediate values.  Portable programs should not rely on that.  If you use &lt;tt&gt;eq?&lt;/tt&gt; on block objects, their pointers will be compared.  That means it checks whether they are &lt;i&gt;one and the same&lt;/i&gt; object.  This can be a useful operation in its own right.&lt;/p&gt;
&lt;p&gt;Objects represented by data blocks also have to be tracked by the garbage collector: if there are still references to the block, its data must be copied (recursively) to keep it alive across GC events.&lt;/p&gt;
&lt;p&gt;Here are some &amp;quot;high-level&amp;quot; examples of block objects:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/block-objects.svg" /&gt;&lt;/p&gt;
&lt;p&gt;This picture should look somewhat familiar to students of &lt;a href="https://mitpress.mit.edu/sicp/" class="external"&gt;SICP&lt;/a&gt;: it is reminiscent of the &lt;a href="https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book-Z-H-15.html#%_sec_2.2" class="external"&gt; box-and-pointer notation&lt;/a&gt; used to illustrate the structure of lists. The boxes containing green text represent the object headers.  The header indicates the type of object and the object's size.  It also determines whether the object's data block is a byte block or a block containing Scheme objects: if it contains Scheme objects, the header tells us how many &lt;i&gt;slots&lt;/i&gt; (locations for storing Scheme objects) the object has.  Byte blocks, on the other hand, are opaque and can contain any data.  Their size is stored as a byte count.&lt;/p&gt;
&lt;p&gt;From top to bottom, left to right, these represent the following values:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;tt&gt;(#\a . #\b)&lt;/tt&gt; is a pair containing the character &amp;quot;a&amp;quot; in its &lt;tt&gt;car&lt;/tt&gt; and &amp;quot;b&amp;quot; in its &lt;tt&gt;cdr&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;#(#f 123 456 #f 42)&lt;/tt&gt; is a regular Scheme vector containing fixnums and &lt;i&gt;false&lt;/i&gt; values.&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;&amp;quot;hello&amp;quot;&lt;/tt&gt; is a string consisting of 5 characters (strings are treated as byte vectors in CHICKEN).&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;12.5&lt;/tt&gt; is an inexact representation of the number twelve and a half (a &amp;quot;flonum&amp;quot;).  This is a byte block storing the raw byte value of a C &lt;tt&gt;double&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;(&amp;quot;hello&amp;quot; . (12.5 . ()))&lt;/tt&gt; is the first pair of a proper list which contains a string and a flonum.&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;(12.5 . ())&lt;/tt&gt; is the &lt;tt&gt;cdr&lt;/tt&gt; of that list; a pair containing a number and the end-of-list marker.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;The final two pair objects show that slots (like any &lt;tt&gt;C_word&lt;/tt&gt;) can hold not only immediate values, but also pointers to block objects. This leads us to the question: &lt;i&gt;how to differentiate between a pointer to an object and an immediate object?&lt;/i&gt;&lt;/p&gt;&lt;a href="#bit-fiddling"&gt;
&lt;h2 id="bit-fiddling"&gt;Bit fiddling&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Most platforms require pointers to words to be &lt;i&gt;aligned on a word boundary&lt;/i&gt;.  Thus, on a 32-bit machine, memory addresses will always have zero in the lower 2 bits, because we can only point to multiples of 4 bytes.  On a 64-bit machine, word addresses will have zero in the lower 3 bits.&lt;/p&gt;
&lt;p&gt;Because the lower two bits are never used, we can perform a simple trick: any value that has either of the lower two bits set cannot be a word pointer, so we &lt;i&gt;enforce&lt;/i&gt; immediate objects to have either bit set.  It may feel like a gross hack to people who are used to working with &amp;quot;clean&amp;quot;, high-level C code, but it is a technique which goes back a long way: &lt;a href="https://people.csail.mit.edu/riastradh/t/adams86orbit.pdf" class="external"&gt;Orbit&lt;/a&gt;, one of the earliest optimising compilers for Scheme, did exactly the same thing.  Other modern Schemes like &lt;a href="http://www.ccs.neu.edu/home/lth/larceny/notes/note2-repr.html" class="external"&gt;Larceny&lt;/a&gt; and &lt;a href="https://github.com/feeley/gambit/blob/df07fb32d1399ad148bf7df413b209a960fd6c02/lib/mem.c#L92" class="external"&gt;Gambit&lt;/a&gt; do the same thing.  Even &lt;a href="http://mumble.net/~jar/pubs/lsc.pdf#page=4" class="external"&gt;Scheme48&lt;/a&gt;, which is probably &lt;i&gt;the&lt;/i&gt; cleanest Scheme implementation, uses tagged words. Other Lisps use this representation as well. See &lt;a href="https://github.com/sbcl/sbcl/blob/bdf211ee45e102a28d0a973842a7a948d35ef602/doc/internals/objects-in-memory.texinfo" class="external"&gt; Steel Bank Common Lisp&lt;/a&gt;, for example.&lt;/p&gt;
&lt;p&gt;Many other dynamic languages don't use a packed data representation like this.  Many prefer the simpler but bulkier &lt;tt&gt;struct&lt;/tt&gt; representation.  At the other end of the spectrum, we have statically typed, non-garbage collected languages.  They generally don't need to store the type of a value along with it.  Instead, they can directly store the &lt;i&gt;&amp;quot;un-boxed&amp;quot;&lt;/i&gt; value in memory.  This, and the relation to garbage collection, is explained rather well in Appel's 1989 paper &lt;a href="http://www.cs.princeton.edu/~appel/papers/142.pdf" class="external"&gt;&amp;quot;Runtime Tags Aren't Necessary&amp;quot;&lt;/a&gt;.&lt;/p&gt;&lt;a href="#representation-of-objects"&gt;
&lt;h3 id="representation-of-objects"&gt;Representation of objects&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;We've learned how CHICKEN distinguishes between pointers to (block) objects and immediate values.  Now we will look into the nitty-gritty details of the object representation.&lt;/p&gt;
&lt;p&gt;We can make the following breakdown of bit patterns (assuming a 32-bit platform):&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/object-bits.svg" /&gt;&lt;/p&gt;
&lt;p&gt;This shows that the lower two bits can be used to distinguish between block objects (zero) and immediate objects (nonzero).  For immediate objects, the low bit can be used to distinguish between fixnum objects and other kinds of immediate objects.  The colouring indicates which bits are used for tagging objects of that kind.  The uncoloured bits are used for representing the object being stored.&lt;/p&gt;
&lt;p&gt;Fixnums are distinguished from &amp;quot;other immediate&amp;quot; values because fixnums are so incredibly common: they are used for indexing into strings, loop counters and many calculations.  These have to be represented as efficiently as possible while storing the widest possible range of values.  Run time type checking for fixnums should use as few CPU instructions as possible.&lt;/p&gt;
&lt;p&gt;The &amp;quot;other immediate&amp;quot; types are further differentiated through the top two bits of the lower nibble:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/immediate-bits.svg" /&gt;&lt;/p&gt;
&lt;p&gt;The unused &amp;quot;other immediate&amp;quot; type of &lt;tt&gt;0010&lt;/tt&gt; is reserved for future use. To get a good feel for the representation of &lt;i&gt;immediates&lt;/i&gt;, let us look at a few example bit patterns.  I'll also show you how to construct them in C.&lt;/p&gt;&lt;a href="#bit-patterns-of-immediate-values"&gt;
&lt;h3 id="bit-patterns-of-immediate-values"&gt;Bit patterns of immediate values&lt;/h3&gt;&lt;/a&gt;&lt;a href="#fixnums"&gt;
&lt;h4 id="fixnums"&gt;Fixnums&lt;/h4&gt;&lt;/a&gt;
&lt;p&gt;&lt;img src="/pics/fixnums.svg" /&gt;&lt;/p&gt;
&lt;p&gt;These small integer values are stored in regular old &lt;a href="https://en.wikipedia.org/wiki/Two%27s_complement" class="external"&gt;two's complement&lt;/a&gt; representation, like the CPU uses.  The lowest bit is always 1, due to the fixnum tag bit.  The highest bit is used to determine the sign of the number.&lt;/p&gt;
&lt;p&gt;The &lt;tt&gt;C_fix()&lt;/tt&gt; macro shifts its argument one bit to the left, and sets the lower bit through a bit-wise OR with 1.  To convert a Scheme fixnum back to a C integer, you can use the &lt;tt&gt;C_unfix()&lt;/tt&gt; macro.  This shifts its argument one bit to the right.&lt;/p&gt;
&lt;p&gt;You might wonder what happens when you calculate or enter a very large integer.  In CHICKEN 4, it will be coerced to a flonum.  In CHICKEN 5, it will be stored as a bignum.  Bignums are block objects, not immediates, because they may be arbitrarily large.&lt;/p&gt;&lt;a href="#booleans"&gt;
&lt;h4 id="booleans"&gt;Booleans&lt;/h4&gt;&lt;/a&gt;
&lt;p&gt;&lt;img src="/pics/booleans.svg" /&gt;&lt;/p&gt;
&lt;p&gt;That's a very large bit space for only two values.  However, reserving a special type tag just for booleans simplifies type detection code: we only have to compare the lower four bits with &lt;tt&gt;0110&lt;/tt&gt; to check whether an object is a boolean.&lt;/p&gt;&lt;a href="#characters"&gt;
&lt;h4 id="characters"&gt;Characters&lt;/h4&gt;&lt;/a&gt;
&lt;p&gt;&lt;img src="/pics/characters.svg" /&gt;&lt;/p&gt;
&lt;p&gt;Characters do not make full use of the available bits, because the lower byte's high nibble is always &lt;tt&gt;0000&lt;/tt&gt;.  This means that only 24 bits are available for representing the character on 32-bit platforms. Luckily, this is enough for representing the full Unicode range.  If Unicode ever starts using up a bigger code space, we can always sneak in 4 more bits.&lt;/p&gt;&lt;a href="#special-objects"&gt;
&lt;h4 id="special-objects"&gt;Special objects&lt;/h4&gt;&lt;/a&gt;
&lt;p&gt;&lt;img src="/pics/specials.svg" /&gt;&lt;/p&gt;
&lt;p&gt;This list is exhaustive: currently there are only four special objects.  There is a lot of room for adding other special objects, if that ever becomes necessary.&lt;/p&gt;
&lt;p&gt;The &amp;quot;unbound variable&amp;quot; representation cannot be captured by a program: when it is evaluated, it immediately raises an exception.  This is its intended function.&lt;/p&gt;&lt;a href="#a-closer-look-at-block-objects"&gt;
&lt;h3 id="a-closer-look-at-block-objects"&gt;A closer look at block objects&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Now that we know all about immediate values, let's turn to block objects.  These are represented by a pointer to a C structure with a header and a data block.  Slightly simplified, it looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="special"&gt;#define C_uword  unsigned C_word
&lt;/span&gt;&lt;span class="special"&gt;#define C_header C_uword
&lt;/span&gt;
&lt;span class="symbol"&gt;typedef&lt;/span&gt; &lt;span class="symbol"&gt;struct&lt;/span&gt;
&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  C_header header;
  C_word data&lt;span class="paren2"&gt;[&lt;span class="default"&gt;&lt;/span&gt;]&lt;/span&gt;;    &lt;span class="comment"&gt;/* Variable-length array: header determines length */&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt; C_SCHEME_BLOCK;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The header's bit pattern is broken up into three parts:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/header-bits.svg" /&gt;&lt;/p&gt;
&lt;p&gt;The bottom 24 bits encode the size of the object.  On 64-bit machines, the bottom 56 bits are used for the size.  The middle 4 bits encode the type of the object.  The top 4 bits encode special properties to make the garbage collector's work easier:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;tt&gt;C_GC_FORWARDING_BIT&lt;/tt&gt; indicates this object has been forwarded elsewhere.  To find the object at its new location, the entire header is shifted to the left (which shifts out this bit).  Then, the value is reinterpreted as a pointer.  Remember, the lowest two bits of word pointers are always zero, so we can do this with impunity!&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;C_BYTEBLOCK_BIT&lt;/tt&gt; indicates this is a byte blob (size bits are interpreted in bytes, not words).&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;C_SPECIALBLOCK_BIT&lt;/tt&gt; indicates that the first slot is special and should be skipped by the GC.&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;C_8ALIGN_BIT&lt;/tt&gt; indicates that for this object, alignment must be maintained at an 8-byte boundary.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;The type bits are assigned incrementally.  There is room for 16 types, only 2 of which are currently unused.  Let's look at the definitions, which should also help to explain the practical use of the latter 3 GC bits:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="special"&gt;#define C_SYMBOL_TYPE            (0x01000000L)
&lt;/span&gt;&lt;span class="special"&gt;#define C_STRING_TYPE            (0x02000000L | C_BYTEBLOCK_BIT)
&lt;/span&gt;&lt;span class="special"&gt;#define C_PAIR_TYPE              (0x03000000L)
&lt;/span&gt;&lt;span class="special"&gt;#define C_CLOSURE_TYPE           (0x04000000L | C_SPECIALBLOCK_BIT)
&lt;/span&gt;&lt;span class="special"&gt;#define C_FLONUM_TYPE            (0x05000000L | C_BYTEBLOCK_BIT | C_8ALIGN_BIT)
&lt;/span&gt;&lt;span class="comment"&gt;/*      unused                   (0x06000000L ...) */&lt;/span&gt;
&lt;span class="special"&gt;#define C_PORT_TYPE              (0x07000000L | C_SPECIALBLOCK_BIT)
&lt;/span&gt;&lt;span class="special"&gt;#define C_STRUCTURE_TYPE         (0x08000000L)
&lt;/span&gt;&lt;span class="special"&gt;#define C_POINTER_TYPE           (0x09000000L | C_SPECIALBLOCK_BIT)
&lt;/span&gt;&lt;span class="special"&gt;#define C_LOCATIVE_TYPE          (0x0a000000L | C_SPECIALBLOCK_BIT)
&lt;/span&gt;&lt;span class="special"&gt;#define C_TAGGED_POINTER_TYPE    (0x0b000000L | C_SPECIALBLOCK_BIT)
&lt;/span&gt;&lt;span class="special"&gt;#define C_SWIG_POINTER_TYPE      (0x0c000000L | C_SPECIALBLOCK_BIT)
&lt;/span&gt;&lt;span class="special"&gt;#define C_LAMBDA_INFO_TYPE       (0x0d000000L | C_BYTEBLOCK_BIT)
&lt;/span&gt;&lt;span class="comment"&gt;/*      unused                   (0x0e000000L ...) */&lt;/span&gt;
&lt;span class="special"&gt;#define C_BUCKET_TYPE            (0x0f000000L)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Most of the types should be self-explanatory to a seasoned Schemer, but a few things deserve further explanation.&lt;/p&gt;
&lt;p&gt;You'll note that in the &lt;tt&gt;STRING&lt;/tt&gt; type tag, &lt;tt&gt;C_BYTEBLOCK_BIT&lt;/tt&gt; is also set, for obvious reasons: strings do not consist of &lt;i&gt;slots&lt;/i&gt; containing Scheme values, but of &lt;i&gt;bytes&lt;/i&gt;, which are opaque.  Because the header's &lt;i&gt;size&lt;/i&gt; bits store the length in bytes instead of in words, we can spot a very important limitation: CHICKEN strings can only hold 16 &lt;a href="https://en.wikipedia.org/wiki/Mebibyte" class="external"&gt;MiB&lt;/a&gt; of data on a 32-bit machine (on a 64-bit machine, strings are &amp;quot;limited&amp;quot; to 65536 &lt;a href="https://en.wikipedia.org/wiki/Tebibyte" class="external"&gt;TiB&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The &lt;tt&gt;CLOSURE&lt;/tt&gt; type uses &lt;tt&gt;C_SPECIALBLOCK_BIT&lt;/tt&gt;.  This indicates to the garbage collector that the &lt;i&gt;first&lt;/i&gt; slot contains a raw non-Scheme value.  In the case of a closure, it contains a pointer to a C function.  The other slots contain free variables that were closed over (&amp;quot;captured&amp;quot;) by the lambda, which are normal Scheme objects.  The compiled C function &amp;quot;knows&amp;quot; which variable lives in which slot.&lt;/p&gt;
&lt;p&gt;The &lt;tt&gt;FLONUM&lt;/tt&gt; type uses &lt;tt&gt;C_BYTEBLOCK_BIT&lt;/tt&gt;, because an un-boxed C &lt;tt&gt;double&lt;/tt&gt; value is not a Scheme object: we want to treat the data as an opaque blob.  On a 32-bit system, the double will take up &lt;i&gt;two&lt;/i&gt; machine words, so we can't use &lt;tt&gt;C_SPECIALBLOCK_BIT&lt;/tt&gt;.  The header will therefore hold the value 8 as its size.  It also has another GC bit: &lt;tt&gt;C_8ALIGN_BIT&lt;/tt&gt;.  This ensures that the 64-bit double is aligned on a 8-byte boundary, to avoid unaligned access on 32-bit systems. This adds some complexity to garbage collection and memory allocation.&lt;/p&gt;
&lt;p&gt;The &lt;tt&gt;STRUCTURE&lt;/tt&gt; type refers to a &lt;a href="http://srfi.schemers.org/srfi-9/srfi-9.html" class="external"&gt;SRFI-9&lt;/a&gt; type of record object.  Its slots hold the record's fields, and the accessors and constructors &amp;quot;know&amp;quot; which field is stored at which index.&lt;/p&gt;
&lt;p&gt;The &lt;tt&gt;POINTER&lt;/tt&gt; type holds a raw C pointer inside a Scheme object. Again, because C pointers are not Scheme objects, the object's first (and only) slot is treated specially, via &lt;tt&gt;C_SPECIALBLOCK_BIT&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;tt&gt;LOCATIVE&lt;/tt&gt; type represents a &lt;a href="http://wiki.call-cc.org/man/4/Unit%20lolevel#locatives" class="external"&gt;rather complicated object&lt;/a&gt;.  It acts a bit like a pointer into a slab of memory.  You can use it as a single value which represents a location inside another block object.  This can then be used as an argument to a foreign function that expects a pointer.  Its first slot holds a raw pointer.  The other slots hold the offset, the type of pointer (encoded as fixnum) and the original object, unless it is a &lt;i&gt;weak&lt;/i&gt; reference.&lt;/p&gt;
&lt;p&gt;The &lt;tt&gt;TAGGED_POINTER&lt;/tt&gt; type is exactly like &lt;tt&gt;POINTER&lt;/tt&gt;, but it has an extra user-defined &lt;i&gt;tag&lt;/i&gt;.  This can make it easier for code to identify the pointer's type.  The tag is a Scheme value held in its second slot.&lt;/p&gt;
&lt;p&gt;The &lt;tt&gt;SWIG_POINTER&lt;/tt&gt; has been removed in CHICKEN 5 and was used for compatibility with &lt;a href="http://www.swig.org" class="external"&gt;SWIG&lt;/a&gt;.  It is basically the same as &lt;tt&gt;POINTER&lt;/tt&gt;, with additional SWIG data added to it.&lt;/p&gt;
&lt;p&gt;The &lt;tt&gt;LAMBDA_INFO&lt;/tt&gt; type stores procedure introspection information (mostly for debugging).&lt;/p&gt;
&lt;p&gt;The &lt;tt&gt;BUCKET&lt;/tt&gt; type is a special internal pair-like object which is used in the linked list of symbols under a hash table bucket in the symbol table.  It does not count as a reference, so that symbols can be garbage collected when &lt;i&gt;only&lt;/i&gt; the symbol table still refers to them.&lt;/p&gt;
&lt;p&gt;So far, the only numeric types we've seen are fixnums and flonums. What about the other numeric types?  After all, CHICKEN 5 will (finally) have a full &lt;a href="http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2.1" class="external"&gt;numeric tower&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;In CHICKEN 5, rational and complex numbers are viewed as two simpler numbers stuck together.  They're stored as records with a special tag, which the run-time system recognises.  Bignums are a different story altogether.  When I first implemented them, they used one of the two unused header types in the list above.  For various reasons I won't go into now, they are now also represented as a record with a special tag and a slot that refers to the byte blob containing the actual bignum value.  Perhaps this is something for a later blog post.&lt;/p&gt;&lt;a href="#putting-it-all-together-in-the-garbage-collector"&gt;
&lt;h2 id="putting-it-all-together-in-the-garbage-collector"&gt;Putting it all together in the garbage collector&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;So far, all of this perhaps sounds rather arbitrary and complex.  The data representation is finely tuned to fit the garbage collector, and vice versa, so it may help to see how this simplifies the garbage collector.&lt;/p&gt;
&lt;p&gt;The way the data representation is set up, the garbage collector only has to perform a few very basic checks.  It does not need to know about any of the data types &lt;i&gt;at all&lt;/i&gt;, it only needs to look at the special GC bits, and the size of an object!&lt;/p&gt;
&lt;p&gt;Now we're finally ready to understand the &lt;b&gt;heart&lt;/b&gt; of the garbage collector, which scans the live data and marks nested objects.  This part of CHICKEN implements the Cheney algorithm.  It's only 22 lines of code, without any simplifications.  This is taken &lt;a href="http://code.call-cc.org/cgi-bin/gitweb.cgi?p=chicken-core.git;a=blob;f=runtime.c;h=f592f9354a65039c7cf6e3a5acf892ffa4cbeecc;hb=HEAD#l2857" class="external"&gt;directly from runtime.c&lt;/a&gt;, with comments added for exposition:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="comment"&gt;/* Mark nested values in already moved (marked) blocks
   in breadth-first manner: */&lt;/span&gt;
&lt;span class="symbol"&gt;while&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;heap_scan_top &amp;lt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;gc_mode == GC_MINOR ? C_fromspace_top : tospace_top&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  bp = &lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_SCHEME_BLOCK *&lt;/span&gt;)&lt;/span&gt;heap_scan_top; &lt;span class="comment"&gt;/* Get next object from queue */&lt;/span&gt;

  &lt;span class="comment"&gt;/* If this word is an alignment hole marker, skip it */&lt;/span&gt;
  &lt;span class="symbol"&gt;if&lt;/span&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;*&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;C_word *&lt;/span&gt;)&lt;/span&gt;bp&lt;/span&gt;)&lt;/span&gt; == ALIGNMENT_HOLE_MARKER&lt;/span&gt;)&lt;/span&gt;
    bp = &lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_SCHEME_BLOCK *&lt;/span&gt;)&lt;/span&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_word *&lt;/span&gt;)&lt;/span&gt;bp + 1&lt;/span&gt;)&lt;/span&gt;;

  n = C_header_size&lt;span class="paren2"&gt;(&lt;span class="default"&gt;bp&lt;/span&gt;)&lt;/span&gt;;  &lt;span class="comment"&gt;/* Extract size bits from header */&lt;/span&gt;
  h = bp-&amp;gt;header;         &lt;span class="comment"&gt;/* Remember header for masking other bits */&lt;/span&gt;
  bytes = &lt;span class="paren2"&gt;(&lt;span class="default"&gt;h &amp;amp; C_BYTEBLOCK_BIT&lt;/span&gt;)&lt;/span&gt; ? n : n * &lt;span class="symbol"&gt;sizeof&lt;/span&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_word&lt;/span&gt;)&lt;/span&gt;;  &lt;span class="comment"&gt;/* Size in bytes */&lt;/span&gt;
  p = bp-&amp;gt;data;           &lt;span class="comment"&gt;/* Data block (first slot) */&lt;/span&gt;

  &lt;span class="symbol"&gt;if&lt;/span&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;n &amp;gt; 0 &amp;amp;&amp;amp; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;h &amp;amp; C_BYTEBLOCK_BIT&lt;/span&gt;)&lt;/span&gt; == 0&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt; &lt;span class="comment"&gt;/* Contains slots, not bytes? */&lt;/span&gt;
    &lt;span class="symbol"&gt;if&lt;/span&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;h &amp;amp; C_SPECIALBLOCK_BIT&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren3"&gt;{&lt;span class="default"&gt; &lt;span class="comment"&gt;/* Skip first word (not a Scheme object) */&lt;/span&gt;
      --n;
      ++p;
    &lt;/span&gt;}&lt;/span&gt;

    &lt;span class="symbol"&gt;while&lt;/span&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;n--&lt;/span&gt;)&lt;/span&gt; mark&lt;span class="paren3"&gt;(&lt;span class="default"&gt;p++&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* Mark Scheme objects in data slots */&lt;/span&gt;
  &lt;/span&gt;}&lt;/span&gt;

  &lt;span class="comment"&gt;/* Advance onto next word just after object */&lt;/span&gt;
  heap_scan_top = &lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_byte *&lt;/span&gt;)&lt;/span&gt;bp + C_align&lt;span class="paren2"&gt;(&lt;span class="default"&gt;bytes&lt;/span&gt;)&lt;/span&gt; + &lt;span class="symbol"&gt;sizeof&lt;/span&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_word&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The comment at the start refers to the fact that the &amp;quot;tip of the iceberg&amp;quot; of live data has already been copied; this code scans that set for nested objects referred to by those live objects.  See my &lt;a href="/posts/internals-gc.html" class="internal"&gt;post about the garbage collector&lt;/a&gt; for more about how the GC and Cheney's algorithm work.&lt;/p&gt;
&lt;p&gt;If we're in a minor GC, this code scans over the &lt;tt&gt;fromspace&lt;/tt&gt;, which is the memory area into which the nursery objects will be copied.  If we're in a major GC, we're scanning over &lt;tt&gt;tospace&lt;/tt&gt;, which is the other half of the heap, to which the &lt;tt&gt;fromspace&lt;/tt&gt; will be copied.&lt;/p&gt;
&lt;p&gt;The code above simply advances the &lt;tt&gt;heap_scan_top&lt;/tt&gt; pointer over the objects we need to look at until we hit the end of this space.  It then checks for an &lt;tt&gt;ALIGNMENT_HOLE_MARKER&lt;/tt&gt;, which is a magic value that gets used as a placeholder to indicate that this machine word should be skipped.  This placeholder may get inserted when allocating a &lt;tt&gt;C_8ALIGN_BIT&lt;/tt&gt; object, to avoid unaligned access.&lt;/p&gt;
&lt;p&gt;Next, the size (in bytes) of the object is determined, based on the &lt;tt&gt;C_BYTEBLOCK_BIT&lt;/tt&gt;.  Finally, if it's a data block (&lt;tt&gt;C_BYTEBLOCK_BIT&lt;/tt&gt; is not set), we loop over the data slots.  The first word is skipped if it's indicated as &amp;quot;special&amp;quot; via &lt;tt&gt;C_SPECIALBLOCK_BIT&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;tt&gt;mark()&lt;/tt&gt; call hides the hairy part.  It performs the following steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Check that the word contains a block object.  Otherwise, return because it's an immediate value.&lt;/li&gt;
&lt;li&gt;Check that the word points to memory that's being moved, otherwise return. This avoids copying already copied or evicted data.&lt;/li&gt;
&lt;li&gt;If the object has the &lt;tt&gt;C_GC_FORWARDING_BIT&lt;/tt&gt; set, just update the marked slot with the new location the object was forwarded to, and return.&lt;/li&gt;
&lt;li&gt;If we're on a 32-bit machine, the object to be copied has the &lt;tt&gt;C_8ALIGN_BIT&lt;/tt&gt; set, and the current top of the target heap area is not aligned, insert an &lt;tt&gt;ALIGNMENT_HOLE_MARKER&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;In case the target area is too small to hold the object, interrupt the current GC and trigger the &amp;quot;next&amp;quot; GC type.  This will be a major collection if we're currently doing a minor collection, or a heap reallocating major collection if we're in a regular major collection.&lt;/li&gt;
&lt;li&gt;Finally, copy the object via a simple &lt;tt&gt;memcpy()&lt;/tt&gt;.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Because this is done by &lt;tt&gt;mark()&lt;/tt&gt; and not by the scanning code shown above, all this is &lt;i&gt;only&lt;/i&gt; performed if the object in question is a block object which needs to be copied (the &lt;tt&gt;mark()&lt;/tt&gt; macro inlines the first check).  Just scanning the live data is extremely fast. We can thank the data representation's simplicity for that speed!&lt;/p&gt;&lt;a href="#further-reading"&gt;
&lt;h2 id="further-reading"&gt;Further reading&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;There is a &lt;i&gt;lot&lt;/i&gt; of information about this stuff, but it can be a little hard to find.  Here are a few links I found during my research for this blog post:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://wiki.call-cc.org/man/4/Data%20representation" class="external"&gt;The &amp;quot;Data Representation&amp;quot; section of the CHICKEN manual&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.multicians.org/lcp.html" class="external"&gt;The Multics MACLISP Compiler -- the Basic Hackery -- a Tutorial&lt;/a&gt;.  Contains a description of a radically different data representation based on the BIBOP (BIg Bag Of Pages) scheme.  Also, see if you can spot a reference in the CHICKEN sources!&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dspace.mit.edu/bitstream/handle/1721.1/6278/AIM-420.pdf" class="external"&gt;Data representations in PDP-10 MacLISP&lt;/a&gt;, another technical paper about MacLISP.  Fascinating stuff, if you're a computer history buff.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blob.perl.org/tpc/1998/Perl_Language_and_Modules/Perl%20Illustrated/" class="external"&gt;Perl's data representation&lt;/a&gt; is about as bizarre as the language itself.  See &lt;a href="http://perldoc.perl.org/perlguts.html" class="external"&gt;the perlguts man page&lt;/a&gt; for more details.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.python.org/3/extending/newtypes.html" class="external"&gt;Python's object representation&lt;/a&gt; is yawn-inducingly boring.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://patshaughnessy.net/2012/7/26/objects-classes-and-modules" class="external"&gt;Ruby's object representation&lt;/a&gt; is more Lisp-like: some types are stored as immediate values.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://caml.inria.fr/pub/papers/xleroy-unboxing-tic97.pdf" class="external"&gt;The effectiveness of type-based unboxing&lt;/a&gt; explains how static languages with polymorphism (such as the ML family) still need to store &lt;i&gt;some&lt;/i&gt; type information at run-time, and explores various representations.  It concludes with the counter-intuitive notion that storing tagged values can be even &lt;i&gt;more efficient&lt;/i&gt; than always storing the values in un-boxed form.&lt;/li&gt;
&lt;li&gt;The book &lt;i&gt;Real World OCaml&lt;/i&gt; has a &lt;a href="https://dev.realworldocaml.org/runtime-memory-layout.html" class="external"&gt;chapter on OCaml's memory representation of values&lt;/a&gt;, which turns out to be remarkably similar to CHICKEN's.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.cs.princeton.edu/research/techreps/TR-220-89" class="external"&gt;A Runtime System&lt;/a&gt; describes the run-time system of Standard ML of New Jersey, including the data representation and the garbage collector.&lt;/li&gt;&lt;/ul&gt;</content>
    <id>tag:more-magic,2015-08-16:/posts/internals-data-representation.html</id>
    <published>2015-08-16T12:19:13Z</published>
    <title type="text">CHICKEN internals: data representation</title>
    <updated>2015-08-16T12:19:13Z</updated>
    <link href="https://www.more-magic.net/posts/internals-data-representation.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;When you're writing Scheme code in CHICKEN it's sometimes necessary to make a little excursion to C.  For example, you're trying to call a C library, you're writing extremely performance-critical code, or you're working on something that's best expressed in C, such as code that requires a lot of bit-twiddling.&lt;/p&gt;
&lt;p&gt;This post contains a lot of code, including generated C code.  If you get too tired to absorb it, it's probably best to stop reading and pick it up again later.&lt;/p&gt;&lt;a href="#a-basic-example-of-invoking-c-code-from-chicken"&gt;
&lt;h2 id="a-basic-example-of-invoking-c-code-from-chicken"&gt;A basic example of invoking C code from CHICKEN&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;This is one of CHICKEN's strengths: the ability to quickly drop down to C for a small bit of code, and return its result to Scheme:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;import foreign&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; ilen
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;foreign-lambda* long &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;unsigned-long x&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;unsigned long y;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;long n = 0;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;#ifdef C_SIXTY_FOUR&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;y = x &amp;gt;&amp;gt; 32; if (y != 0) { n += 32; x = y; }&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;#endif&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;y = x &amp;gt;&amp;gt; 16; if (y != 0) { n += 16; x = y; }&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;y = x &amp;gt;&amp;gt;  8; if (y != 0) { n +=  8; x = y; }&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;y = x &amp;gt;&amp;gt;  4; if (y != 0) { n +=  4; x = y; }&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;y = x &amp;gt;&amp;gt;  2; if (y != 0) { n +=  2; x = y; }&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;y = x &amp;gt;&amp;gt;  1; if (y != 0) C_return(n + 2);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;C_return(n + x);&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;print &lt;span class="string"&gt;&amp;quot;Please enter a number&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;print &lt;span class="string"&gt;&amp;quot;The length of your integer in bits is &amp;quot;&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;ilen &lt;span class="paren3"&gt;(&lt;span class="default"&gt;read&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This example is taken from a wonderful little book called &lt;a href="http://www.hackersdelight.org/" class="external"&gt;&amp;quot;Hacker's Delight&amp;quot;&lt;/a&gt;, by Henry S. Warren.  It calculates the number of bits required to represent an unsigned integer (its &amp;quot;length&amp;quot;).  By the way, this procedure is provided by the &lt;a href="http://wiki.call-cc.org/eggref/4/numbers" class="external"&gt;numbers egg&lt;/a&gt; as &lt;tt&gt;integer-length&lt;/tt&gt;.  The algorithm is implementable in Scheme, but at least a direct translation to Scheme is nowhere as readable as it is in C:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;ilen x&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;y 0&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;n 0&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;cond-expand
      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;64bit
       &lt;span class="paren5"&gt;(&lt;span class="default"&gt;set! y &lt;span class="paren6"&gt;(&lt;span class="default"&gt;arithmetic-shift x -32&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
       &lt;span class="paren5"&gt;(&lt;span class="default"&gt;unless &lt;span class="paren6"&gt;(&lt;span class="default"&gt;zero? y&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren6"&gt;(&lt;span class="default"&gt;set! n &lt;span class="paren1"&gt;(&lt;span class="default"&gt;+ n 32&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren6"&gt;(&lt;span class="default"&gt;set! x y&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;else&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;set! y &lt;span class="paren4"&gt;(&lt;span class="default"&gt;arithmetic-shift x -16&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;unless &lt;span class="paren4"&gt;(&lt;span class="default"&gt;zero? y&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;set! n &lt;span class="paren5"&gt;(&lt;span class="default"&gt;+ n 16&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;set! x y&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;set! y &lt;span class="paren4"&gt;(&lt;span class="default"&gt;arithmetic-shift x -8&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;unless &lt;span class="paren4"&gt;(&lt;span class="default"&gt;zero? y&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;set! n &lt;span class="paren5"&gt;(&lt;span class="default"&gt;+ n 8&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;set! x y&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;set! y &lt;span class="paren4"&gt;(&lt;span class="default"&gt;arithmetic-shift x -4&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;unless &lt;span class="paren4"&gt;(&lt;span class="default"&gt;zero? y&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;set! n &lt;span class="paren5"&gt;(&lt;span class="default"&gt;+ n 4&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;set! x y&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;set! y &lt;span class="paren4"&gt;(&lt;span class="default"&gt;arithmetic-shift x -2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;unless &lt;span class="paren4"&gt;(&lt;span class="default"&gt;zero? y&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;set! n &lt;span class="paren5"&gt;(&lt;span class="default"&gt;+ n 2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;set! x y&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;set! y &lt;span class="paren4"&gt;(&lt;span class="default"&gt;arithmetic-shift x -1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;if&lt;/span&gt;&lt;/i&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;not &lt;span class="paren5"&gt;(&lt;span class="default"&gt;zero? y&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;+ n 2&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;+ n x&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The performance of the Scheme version is also going to be less than that of the C version.  All in all, plenty of good reasons to prefer integration with C.  There's no shame in that: most fast languages forego &amp;quot;pure&amp;quot; implementations in favour of C for performance reasons. The only difference is that &lt;a href="http://nodejs.org/api/addons.html" class="external"&gt;calling C&lt;/a&gt; in &lt;a href="http://www.onlamp.com/pub/a/onlamp/2004/11/18/extending_ruby.html" class="external"&gt;other languages&lt;/a&gt; is often &lt;a href="https://docs.python.org/3/c-api/index.html" class="external"&gt;a bit more work&lt;/a&gt;.&lt;/p&gt;&lt;a href="#analysing-the-generated-code"&gt;
&lt;h3 id="analysing-the-generated-code"&gt;Analysing the generated code&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;In this section we'll unveil the internal magic which makes C so easily integrated with Scheme.  You can skip this section if you aren't interested in low-level details.&lt;/p&gt;
&lt;p&gt;As you might have noticed, the C code in the example above contains one unfamiliar construct: It uses &lt;tt&gt;C_return()&lt;/tt&gt; to return the result. If you inspect the code generated by CHICKEN after compiling it via &lt;tt&gt;csc -k test.scm&lt;/tt&gt;, you'll see that it inserts some magic to convert the C number to a Scheme object.  I've added some annotations and indented for readability:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="comment"&gt;/* Local macro definition to convert returned long to a Scheme object. */&lt;/span&gt;
&lt;span class="special"&gt;#define return(x) \
&lt;/span&gt;  C_cblock C_r = &lt;span class="paren1"&gt;(&lt;span class="default"&gt;C_long_to_num&lt;span class="paren2"&gt;(&lt;span class="default"&gt;&amp;amp;C_a,&lt;span class="paren3"&gt;(&lt;span class="default"&gt;x&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;; &lt;span class="symbol"&gt;goto&lt;/span&gt; C_ret; C_cblockend

&lt;span class="comment"&gt;/* Prototype declaring the stub procedure as static, returning a
 * C_word (Scheme object) and passing arguments through registers.
 * It&amp;#x27;s not strictly necessary in this case.
 */&lt;/span&gt;
&lt;span class="symbol"&gt;static&lt;/span&gt; C_word C_fcall stub7&lt;span class="paren1"&gt;(&lt;span class="default"&gt;C_word C_buf, C_word C_a0&lt;/span&gt;)&lt;/span&gt; C_regparm;

&lt;span class="comment"&gt;/* The stub function: it gets passed a buffer in which Scheme objects get
 * allocated (C_buf) and the numbered arguments C_a0, C_a1, ... C_an.
 */&lt;/span&gt;
C_regparm &lt;span class="symbol"&gt;static&lt;/span&gt; C_word C_fcall stub7&lt;span class="paren1"&gt;(&lt;span class="default"&gt;C_word C_buf, C_word C_a0&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  C_word C_r = C_SCHEME_UNDEFINED, &lt;span class="comment"&gt;/* Return value, mutated by return() macro */&lt;/span&gt;
        *C_a=&lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_word*&lt;/span&gt;)&lt;/span&gt;C_buf;     &lt;span class="comment"&gt;/* Allocation pointer used by return() macro */&lt;/span&gt;

  &lt;span class="comment"&gt;/* Conversion of input argument from Scheme to C */&lt;/span&gt;
  &lt;span class="symbol"&gt;unsigned&lt;/span&gt; &lt;span class="symbol"&gt;long&lt;/span&gt; x = &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="symbol"&gt;unsigned&lt;/span&gt; &lt;span class="symbol"&gt;long&lt;/span&gt; &lt;/span&gt;)&lt;/span&gt;C_num_to_unsigned_long&lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_a0&lt;/span&gt;)&lt;/span&gt;;

  &lt;span class="comment"&gt;/* Start of our own code from the foreign-lambda* body, as-is */&lt;/span&gt;
  &lt;span class="symbol"&gt;unsigned&lt;/span&gt; &lt;span class="symbol"&gt;long&lt;/span&gt; y;
  &lt;span class="symbol"&gt;long&lt;/span&gt; n = 0;
&lt;span class="special"&gt;#ifdef C_SIXTY_FOUR
&lt;/span&gt;  y = x &amp;gt;&amp;gt; 32; &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;y != 0&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt; n += 32; x = y; &lt;/span&gt;}&lt;/span&gt;
&lt;span class="special"&gt;#endif
&lt;/span&gt;  y = x &amp;gt;&amp;gt; 16; &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;y != 0&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt; n += 16; x = y; &lt;/span&gt;}&lt;/span&gt;
  y = x &amp;gt;&amp;gt;  8; &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;y != 0&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt; n +=  8; x = y; &lt;/span&gt;}&lt;/span&gt;
  y = x &amp;gt;&amp;gt;  4; &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;y != 0&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt; n +=  4; x = y; &lt;/span&gt;}&lt;/span&gt;
  y = x &amp;gt;&amp;gt;  2; &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;y != 0&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt; n +=  2; x = y; &lt;/span&gt;}&lt;/span&gt;
  y = x &amp;gt;&amp;gt;  1; &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;y != 0&lt;/span&gt;)&lt;/span&gt; C_return&lt;span class="paren2"&gt;(&lt;span class="default"&gt;n + 2&lt;/span&gt;)&lt;/span&gt;;
  C_return&lt;span class="paren2"&gt;(&lt;span class="default"&gt;n + x&lt;/span&gt;)&lt;/span&gt;;

C_ret: &lt;span class="comment"&gt;/* Label for goto in the return() macro */&lt;/span&gt;
&lt;span class="special"&gt;#undef return
&lt;/span&gt;  &lt;span class="symbol"&gt;return&lt;/span&gt; C_r; &lt;span class="comment"&gt;/* Regular C return */&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;

&lt;span class="comment"&gt;/* chicken.h contains the following: */&lt;/span&gt;
&lt;span class="special"&gt;#define C_return(x)              return(x)
&lt;/span&gt;&lt;span class="special"&gt;#define C_cblock                 do{
&lt;/span&gt;&lt;span class="special"&gt;#define C_cblockend              }while(0)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;In the &lt;tt&gt;foreign-lambda*&lt;/tt&gt;, I used &lt;tt&gt;C_return&lt;/tt&gt; for clarity: I could have just used &lt;tt&gt;return&lt;/tt&gt; with parentheses, which will get expanded by the C preprocessor.  This is somewhat confusing: &lt;tt&gt;return n + x;&lt;/tt&gt; will result in an error, whereas &lt;tt&gt;return(n+x);&lt;/tt&gt; will do the same as &lt;tt&gt;C_return(n+x);&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;tt&gt;return&lt;/tt&gt; macro calls &lt;tt&gt;C_long_to_num&lt;/tt&gt;, which will construct a Scheme object, which is either a fixnum (small exact integer) or a flonum (floating-point inexact number), depending on the platform and the size of the returned value.  Hopefully, in CHICKEN 5 it will be either a fixnum or a bignum - that way, it'll always be an exact integer.&lt;/p&gt;
&lt;p&gt;Because these number objects need to get allocated on the stack to integrate with the garbage collector, the calling code needs to set aside enough memory on the stack to fit these objects.  That's what the &lt;tt&gt;C_buf&lt;/tt&gt; argument is for: it's a pointer to this area.  In CHICKEN, a whole lot of type punning is going on, so it's passed as a regular &lt;tt&gt;C_word&lt;/tt&gt; rather than as a proper pointer, but let's ignore that for now.&lt;/p&gt;
&lt;p&gt;The stub function above is used to do the actual work, but in order to integrate it into CHICKEN's calling conventions and garbage collector, an additional wrapper function is generated.  It corresponds to the actual Scheme &amp;quot;ilen&amp;quot; procedure, and looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="comment"&gt;/* ilen in k197 in k194 in k191 */&lt;/span&gt;
&lt;span class="symbol"&gt;static&lt;/span&gt; &lt;span class="symbol"&gt;void&lt;/span&gt; C_ccall f_201&lt;span class="paren1"&gt;(&lt;span class="default"&gt;C_word c, C_word t0, C_word t1, C_word t2&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  C_word tmp &lt;span class="comment"&gt;/* Unused */&lt;/span&gt;; C_word t3; C_word t4; C_word t5;  &lt;span class="comment"&gt;/* Temporaries */&lt;/span&gt;
  C_word ab&lt;span class="paren2"&gt;[&lt;span class="default"&gt;6&lt;/span&gt;]&lt;/span&gt;, *a=ab;     &lt;span class="comment"&gt;/* Memory area set aside on stack for allocation */&lt;/span&gt;

  &lt;span class="symbol"&gt;if&lt;/span&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;c != 3&lt;/span&gt;)&lt;/span&gt; C_bad_argc_2&lt;span class="paren2"&gt;(&lt;span class="default"&gt;c, 3, t0&lt;/span&gt;)&lt;/span&gt;;     &lt;span class="comment"&gt;/* Check argument count is correct */&lt;/span&gt;

  C_check_for_interrupt; &lt;span class="comment"&gt;/* Check pending POSIX signals, and thread timeout */&lt;/span&gt;

  &lt;span class="symbol"&gt;if&lt;/span&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;!C_stack_probe&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&amp;amp;a&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;   &lt;span class="comment"&gt;/* Stack full?  Then perform GC and try again. */&lt;/span&gt;
    C_save_and_reclaim&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="symbol"&gt;void&lt;/span&gt;*&lt;/span&gt;)&lt;/span&gt;tr3, &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="symbol"&gt;void&lt;/span&gt;*&lt;/span&gt;)&lt;/span&gt;f_201, 3, t0, t1, t2&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt;
  t3 = C_a_i_bytevector&lt;span class="paren2"&gt;(&lt;span class="default"&gt;&amp;amp;a,1,C_fix&lt;span class="paren3"&gt;(&lt;span class="default"&gt;4&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;   &lt;span class="comment"&gt;/* Needed to have a proper object */&lt;/span&gt;
  t4 = C_i_foreign_unsigned_integer_argumentp&lt;span class="paren2"&gt;(&lt;span class="default"&gt;t2&lt;/span&gt;)&lt;/span&gt;;   &lt;span class="comment"&gt;/* Check argument type */&lt;/span&gt;
  t5 = t1;                          &lt;span class="comment"&gt;/* The continuation of the call to ilen */&lt;/span&gt;
  &lt;span class="comment"&gt;/* Call stub7 inline, and pass result to continuation: */&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_proc2&lt;/span&gt;)&lt;/span&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="symbol"&gt;void&lt;/span&gt;*&lt;/span&gt;)&lt;/span&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;*&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;C_word*&lt;/span&gt;)&lt;/span&gt;t5+1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;2, t5, stub7&lt;span class="paren3"&gt;(&lt;span class="default"&gt;t3, t4&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The comment at the top indicates the name of the Scheme procedure and its location in the CPS-converted Scheme code.  The &lt;tt&gt;k197 in k194&lt;/tt&gt; etc indicate the nesting in the generated continuations, which can sometimes be useful for debugging.  These continuations can be seen in the CPS-converted code by compiling with &lt;tt&gt;csc -debug 3 test.scm&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Much of the code you might sort-of recognise from the code in my &lt;a href="/posts/internals-gc.html" class="internal"&gt;article about the CHICKEN garbage collector&lt;/a&gt;: The &lt;tt&gt;C_stack_probe()&lt;/tt&gt; corresponds to that post's &lt;tt&gt;fits_on_stack()&lt;/tt&gt;, and &lt;tt&gt;C_save_and_reclaim()&lt;/tt&gt; combines that post's &lt;tt&gt;SCM_save_call()&lt;/tt&gt; and &lt;tt&gt;SCM_minor_GC()&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;All Scheme procedures get compiled down to C functions which receive their argument count (&lt;tt&gt;c&lt;/tt&gt;), the closure/continuation from which they're invoked (&lt;tt&gt;t0&lt;/tt&gt;), so they can access local closure variables (not used here) and in order to perform a GC and re-invoke the closure.  Finally, they receive the continuation of the call (&lt;tt&gt;t1&lt;/tt&gt;) and any procedure arguments (everything after it, here only &lt;tt&gt;t2&lt;/tt&gt;). If a procedure has a variable number of arguments, that will use C's &lt;tt&gt;varargs&lt;/tt&gt; mechanism, which is why passing the argument count to every function is important.  If a function is called with too many or too few arguments, this will &amp;quot;just work&amp;quot;, even if the arguments are declared in the function prototype like here: The function is invoked correctly, but the stack will contain rubbish instead of the expected arguments.  That's why it's important to &lt;i&gt;first&lt;/i&gt; check the argument count, and &lt;i&gt;then&lt;/i&gt; check whether a GC needs to be performed; otherwise, this rubbish gets saved by &lt;tt&gt;save_and_reclaim&lt;/tt&gt; and the GC will attempt to traverse it as if it contained proper Scheme objects, resulting in segfaults or other nasty business.&lt;/p&gt;
&lt;p&gt;The variable &lt;tt&gt;t3&lt;/tt&gt; will contain the buffer in which the return type is stored.  It is wrapped in a byte vector, because this makes it a first-class object understood by the garbage collector.  That's not necessary here, but this code is pretty generic and is also used in cases where it &lt;i&gt;is&lt;/i&gt; necessary.  The &lt;tt&gt;C_word ab[6]&lt;/tt&gt; declaration sets aside enough memory space to hold a flonum or a fixnum, which need at most 4 bytes, plus 2 bytes for the bytevector wrapper.  I will explain these details later in a separate post, but let's assume it's OK for now.&lt;/p&gt;
&lt;p&gt;The argument type gets checked just before calling the C function.  If the argument is not of the correct type, an error is signalled and the function will be aborted.  The returned value is simply the input, so &lt;tt&gt;t4&lt;/tt&gt; will contain the same value as &lt;tt&gt;t2&lt;/tt&gt;.  Similarly, &lt;tt&gt;t1&lt;/tt&gt; gets copied as-is to &lt;tt&gt;t5&lt;/tt&gt;.  Finally, the continuation gets cast to the correct procedure type (again: a lot of type punning.  I will explain this in another post), and invoked with the correct argument count (2), the continuation closure itself, and the return value of the stub function.&lt;/p&gt;&lt;a href="#returning-complex-scheme-objects-from-c"&gt;
&lt;h2 id="returning-complex-scheme-objects-from-c"&gt;Returning complex Scheme objects from C&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;I've tried to explain above how the basic C types get converted to Scheme objects, but what if we want to get crazy and allocate Scheme objects in C?  A simple &lt;tt&gt;foreign-lambda*&lt;/tt&gt; won't suffice, because the compiler has no way of knowing how large a buffer to allocate, and the C function will return, so we'll lose what's on the stack.&lt;/p&gt;
&lt;p&gt;To fix that, we have &lt;tt&gt;foreign-safe-lambda*&lt;/tt&gt;, which will allow us to allocate any object on the stack.  Before such a function is invoked, a minor garbage collection is triggered to clean the stack and ensure we have plenty of allocation room.  Let's look at a simple example. This program displays the list of available network interfaces on a UNIX-like system:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;import foreign&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;foreign-declare &lt;span class="string"&gt;&amp;quot;#include &lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;sys/types.h&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;foreign-declare &lt;span class="string"&gt;&amp;quot;#include &lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;sys/socket.h&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;foreign-declare &lt;span class="string"&gt;&amp;quot;#include &lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;ifaddrs.h&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; interfaces
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;foreign-safe-lambda* scheme-object &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;C_word lst = C_SCHEME_END_OF_LIST, len, str, *a;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;struct ifaddrs *ifa, *i;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;if (getifaddrs(&amp;amp;ifa) != 0)&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  C_return(C_SCHEME_FALSE);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;for (i = ifa; i != NULL; i = i-&amp;gt;ifa_next) {&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  len = strlen(i-&amp;gt;ifa_name);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  a = C_alloc(C_SIZEOF_PAIR + C_SIZEOF_STRING(len));&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  str = C_string(&amp;amp;a, len, i-&amp;gt;ifa_name);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  lst = C_a_pair(&amp;amp;a, str, lst);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;}&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;freeifaddrs(ifa);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;C_return(lst);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;print &lt;span class="string"&gt;&amp;quot;The following interfaces are available: &amp;quot;&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;interfaces&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This functionality is not available in CHICKEN because it's not very portable (it's not in POSIX), so it's a good example of something you might want to use C for.  Please excuse the unSchemely way of error handling by returning &lt;tt&gt;#f&lt;/tt&gt; for now.  We'll fix that in the next chapter.&lt;/p&gt;
&lt;p&gt;Looking at our definition, the &lt;tt&gt;interfaces&lt;/tt&gt; procedure has no arguments, and it returns a &lt;tt&gt;scheme-object&lt;/tt&gt;.  This type indicates to CHICKEN that the returned value is not to be converted but simply used as-is: we'll handle its creation ourselves.&lt;/p&gt;
&lt;p&gt;We declare the return value &lt;tt&gt;lst&lt;/tt&gt;, which gets initialised to the empty list, and two temporary variables: &lt;tt&gt;len&lt;/tt&gt; and &lt;tt&gt;str&lt;/tt&gt;, to keep an intermediate string length and to hold the actual CHICKEN string. The variable &lt;tt&gt;a&lt;/tt&gt; is an allocation pointer.  Then we have the two variables which hold the start of the linked list of interfaces, &lt;tt&gt;ifa&lt;/tt&gt;, and the current iterator through this list, &lt;tt&gt;i&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;We retrieve the linked list (if it fails, returning &lt;tt&gt;#f&lt;/tt&gt;), and scan through it until we hit the end.  For each entry, we simply check the length of the interface name string, we allocate enough room on the stack to hold a pair and a CHICKEN string of the same length (&lt;tt&gt;C_alloc()&lt;/tt&gt; is really just &lt;tt&gt;alloca()&lt;/tt&gt;).  The &lt;tt&gt;C_SIZEOF...&lt;/tt&gt; macros are very convenient to help us calculate the size of an object without having to know its exact representation in memory.  We then create the CHICKEN string using &lt;tt&gt;C_string&lt;/tt&gt;, which is put into the allocated space stored in &lt;tt&gt;a&lt;/tt&gt;, and we create a pair which holds the string in the &lt;tt&gt;car&lt;/tt&gt; and the previous list as its &lt;tt&gt;cdr&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;These allocating &lt;tt&gt;C_a_pair&lt;/tt&gt; and &lt;tt&gt;C_string&lt;/tt&gt; functions accept a pointer to the allocated space (which itself is a pointer).  This means they can advance the pointer's value beyond the object, to the next free position.  This is quite nice, because it allows us to call several allocating functions in a row, with the same pointer, and at the end the pointer points past the object that was allocated last. Finally, we release the memory used by the linked list and return the constructed list.&lt;/p&gt;&lt;a href="#analysing-the-generated-code"&gt;
&lt;h3 id="analysing-the-generated-code"&gt;Analysing the generated code&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Like before, if you're not interested in the details, feel free to skip this section.&lt;/p&gt;
&lt;p&gt;The &lt;tt&gt;interfaces&lt;/tt&gt; foreign code itself compiles down to this function:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="comment"&gt;/* Like before, but no conversion because we &amp;quot;return&amp;quot; a native object: */&lt;/span&gt;
&lt;span class="special"&gt;#define return(x) C_cblock C_r = (((C_word)(x))); goto C_ret; C_cblockend
&lt;/span&gt;
&lt;span class="comment"&gt;/* The prototype _is_ necessary in this case: it declares the function
 * as never returning via C_noret, which maps to __attribute__((noreturn)).
 */&lt;/span&gt;
&lt;span class="symbol"&gt;static&lt;/span&gt; &lt;span class="symbol"&gt;void&lt;/span&gt; C_ccall stub6&lt;span class="paren1"&gt;(&lt;span class="default"&gt;C_word C_c, C_word C_self,
                          C_word C_k, C_word C_buf&lt;/span&gt;)&lt;/span&gt; C_noret;

&lt;span class="comment"&gt;/* The arguments to the stub function now include the argument count,
 * the closure itself and the continuation in addition to the buffer
 * and arguments (none here).  This is a truly &amp;quot;native&amp;quot; CHICKEN function!
 */&lt;/span&gt;
&lt;span class="symbol"&gt;static&lt;/span&gt; &lt;span class="symbol"&gt;void&lt;/span&gt; C_ccall stub6&lt;span class="paren1"&gt;(&lt;span class="default"&gt;C_word C_c, C_word C_self, C_word C_k, C_word C_buf&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  C_word C_r = C_SCHEME_UNDEFINED,
        *C_a = &lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_word *&lt;/span&gt;)&lt;/span&gt;C_buf;

  &lt;span class="comment"&gt;/* Save callback depth; needed if we want to call Scheme functions */&lt;/span&gt;
  &lt;span class="symbol"&gt;int&lt;/span&gt; C_level = C_save_callback_continuation&lt;span class="paren2"&gt;(&lt;span class="default"&gt;&amp;amp;C_a, C_k&lt;/span&gt;)&lt;/span&gt;;

  &lt;span class="comment"&gt;/* Start of our own code, as-is: */&lt;/span&gt;
  &lt;span class="symbol"&gt;struct&lt;/span&gt; ifaddrs *ifa, *i;
  C_word lst = C_SCHEME_END_OF_LIST, len, str, *a;

  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;getifaddrs&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&amp;amp;ifa&lt;/span&gt;)&lt;/span&gt; != 0&lt;/span&gt;)&lt;/span&gt;
    C_return&lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_SCHEME_FALSE&lt;/span&gt;)&lt;/span&gt;;

  &lt;span class="symbol"&gt;for&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;i = ifa; i != NULL; i = i-&amp;gt;ifa_next&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    len = strlen&lt;span class="paren3"&gt;(&lt;span class="default"&gt;i-&amp;gt;ifa_name&lt;/span&gt;)&lt;/span&gt;;
    a = C_alloc&lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_SIZEOF_PAIR + C_SIZEOF_STRING&lt;span class="paren4"&gt;(&lt;span class="default"&gt;len&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
    str = C_string&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&amp;amp;a, len, i-&amp;gt;ifa_name&lt;/span&gt;)&lt;/span&gt;;
    lst = C_a_pair&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&amp;amp;a, str, lst&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt;

  freeifaddrs&lt;span class="paren2"&gt;(&lt;span class="default"&gt;ifa&lt;/span&gt;)&lt;/span&gt;;
  C_return&lt;span class="paren2"&gt;(&lt;span class="default"&gt;lst&lt;/span&gt;)&lt;/span&gt;;

C_ret:
&lt;span class="special"&gt;#undef return
&lt;/span&gt;
  &lt;span class="comment"&gt;/* Pop continuation off callback stack. */&lt;/span&gt;
  C_k = C_restore_callback_continuation2&lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_level&lt;/span&gt;)&lt;/span&gt;;

  C_kontinue&lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_k, C_r&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* Pass return value to continuation. */&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This is not much different from the &lt;tt&gt;foreign-lambda*&lt;/tt&gt; example, but notice that the arguments are different: this stub looks exactly like the C code generated from an actual Scheme continuation: it gets passed the argument count, its own closure and its continuation. Instead of ending with a regular return from C, it invokes a continuation.  This is the crucial difference which integrates our code with the garbage collector: by passing it to the next continuation's C function, the &amp;quot;returned&amp;quot; value is preserved on the stack.  In other words, it is allocated directly in the nursery.&lt;/p&gt;
&lt;p&gt;Even though the stub is a &amp;quot;native&amp;quot; Scheme procedure, a wrapper is still generated: if the &lt;tt&gt;foreign-safe-lambda&lt;/tt&gt; is defined to accept C arguments, it'll still need to convert from Scheme objects, it needs to check the argument count, and it needs to invoke the GC before the procedure can be called:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="comment"&gt;/* interfaces in k197 in k194 in k191 */&lt;/span&gt;
&lt;span class="symbol"&gt;static&lt;/span&gt; &lt;span class="symbol"&gt;void&lt;/span&gt; C_ccall f_201&lt;span class="paren1"&gt;(&lt;span class="default"&gt;C_word c, C_word t0, C_word t1&lt;/span&gt;)&lt;/span&gt;&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  &lt;span class="comment"&gt;/* This is the function that corresponds to the Scheme procedure.
   * This is the first stage of the procedure: we invoke the GC with
   * a continuation which will do conversions and call the C stub.
   */&lt;/span&gt;
  C_word tmp; C_word t2; C_word t3;
  C_word ab&lt;span class="paren2"&gt;[&lt;span class="default"&gt;3&lt;/span&gt;]&lt;/span&gt;, *a = ab;

  &lt;span class="comment"&gt;/* As before: */&lt;/span&gt;
  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;c!=2&lt;/span&gt;)&lt;/span&gt; C_bad_argc_2&lt;span class="paren2"&gt;(&lt;span class="default"&gt;c, 2, t0&lt;/span&gt;)&lt;/span&gt;;

  C_check_for_interrupt;

  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;!C_stack_probe&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&amp;amp;a&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    C_save_and_reclaim&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="symbol"&gt;void&lt;/span&gt;*&lt;/span&gt;)&lt;/span&gt;tr2,&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="symbol"&gt;void&lt;/span&gt;*&lt;/span&gt;)&lt;/span&gt;f_201,2,t0,t1&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt;

  &lt;span class="comment"&gt;/* Create the continuation which will be invoked after GC: */&lt;/span&gt;
  t2 = &lt;span class="paren2"&gt;(&lt;span class="default"&gt;*a = C_CLOSURE_TYPE|2, &lt;span class="comment"&gt;/* A closure of size two: */&lt;/span&gt;
        a&lt;span class="paren3"&gt;[&lt;span class="default"&gt;1&lt;/span&gt;]&lt;/span&gt; = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_word&lt;/span&gt;)&lt;/span&gt;f_205,  &lt;span class="comment"&gt;/* Second stage function of our wrapper, */&lt;/span&gt;
	a&lt;span class="paren3"&gt;[&lt;span class="default"&gt;2&lt;/span&gt;]&lt;/span&gt; = t1,             &lt;span class="comment"&gt;/* and continuation of call to (interfaces). */&lt;/span&gt;
	tmp = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_word&lt;/span&gt;)&lt;/span&gt;a,       &lt;span class="comment"&gt;/* Current value of &amp;quot;a&amp;quot; must be stored in t2...*/&lt;/span&gt;
	a += 3,                &lt;span class="comment"&gt;/* ... but &amp;quot;a&amp;quot; itself gets advanced... */&lt;/span&gt;
	tmp&lt;/span&gt;)&lt;/span&gt;;                  &lt;span class="comment"&gt;/* ... luckily tmp holds original value of a. */&lt;/span&gt;

  C_trace&lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;test.scm:8: ##sys#gc&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* Trace call chain */&lt;/span&gt;

  &lt;span class="comment"&gt;/* lf[1] contains the symbol ##sys#gc.  This invokes its procedure. */&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_proc3&lt;/span&gt;)&lt;/span&gt;C_fast_retrieve_symbol_proc&lt;span class="paren3"&gt;(&lt;span class="default"&gt;lf&lt;span class="paren4"&gt;[&lt;span class="default"&gt;1&lt;/span&gt;]&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;3, *&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;C_word*&lt;/span&gt;)&lt;/span&gt;lf&lt;span class="paren4"&gt;[&lt;span class="default"&gt;1&lt;/span&gt;]&lt;/span&gt;+1&lt;/span&gt;)&lt;/span&gt;,
                                                t2, C_SCHEME_FALSE&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;

&lt;span class="comment"&gt;/* k203 in interfaces in k197 in k194 in k191 */&lt;/span&gt;
&lt;span class="symbol"&gt;static&lt;/span&gt; &lt;span class="symbol"&gt;void&lt;/span&gt; C_ccall f_205&lt;span class="paren1"&gt;(&lt;span class="default"&gt;C_word c, C_word t0, C_word t1&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  &lt;span class="comment"&gt;/* This function gets invoked from the GC triggered by the above function,
   * and is the second stage of our wrapper function.  It is similar to the
   * wrapper from the first example of a regular foreign-lambda.
   */&lt;/span&gt;
  C_word tmp; C_word t2; C_word t3; C_word t4;
  &lt;span class="comment"&gt;/* Enough room for a closure of 2 words (total size 3) and a bytevector
   * of 3 words (total size 4).  This adds up to 7; The missing 1 is to
   * make room for a possible alignment of the bytevector on 32-bit platforms.
   */&lt;/span&gt;
  C_word ab&lt;span class="paren2"&gt;[&lt;span class="default"&gt;8&lt;/span&gt;]&lt;/span&gt;, *a=ab;

  C_check_for_interrupt;

  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;!C_stack_probe&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&amp;amp;a&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    C_save_and_reclaim&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="symbol"&gt;void&lt;/span&gt;*&lt;/span&gt;)&lt;/span&gt;tr2, &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="symbol"&gt;void&lt;/span&gt;*&lt;/span&gt;)&lt;/span&gt;f_205, 2, t0, t1&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt;

  t2 = C_a_i_bytevector&lt;span class="paren2"&gt;(&lt;span class="default"&gt;&amp;amp;a, 1, C_fix&lt;span class="paren3"&gt;(&lt;span class="default"&gt;3&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* Room for one pair */&lt;/span&gt;

  t3 = &lt;span class="paren2"&gt;(&lt;span class="default"&gt;*a = C_CLOSURE_TYPE|2, &lt;span class="comment"&gt;/* Create a closure of size 2: */&lt;/span&gt;
        a&lt;span class="paren3"&gt;[&lt;span class="default"&gt;1&lt;/span&gt;]&lt;/span&gt; = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_word&lt;/span&gt;)&lt;/span&gt;stub6,  &lt;span class="comment"&gt;/* Our foreign-safe-lambda stub function, */&lt;/span&gt;
	a&lt;span class="paren3"&gt;[&lt;span class="default"&gt;2&lt;/span&gt;]&lt;/span&gt; = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;C_word&lt;/span&gt;)&lt;/span&gt;li0&lt;/span&gt;)&lt;/span&gt;,  &lt;span class="comment"&gt;/* and static lambda-info for same (unused). */&lt;/span&gt;
	tmp = &lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_word&lt;/span&gt;)&lt;/span&gt;a,       &lt;span class="comment"&gt;/* Update &amp;quot;a&amp;quot; and return original value, */&lt;/span&gt;
	a += 3,                &lt;span class="comment"&gt;/* exactly like we did in f_201. */&lt;/span&gt;
	tmp&lt;/span&gt;)&lt;/span&gt;;
	
  &lt;span class="comment"&gt;/* Trace procedure name generated by (gensym). Kind of useless :) */&lt;/span&gt;
  C_trace&lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;test.scm:8: g9&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;

  t4 = t3; &lt;span class="comment"&gt;/* Compilation artefact; don&amp;#x27;t worry about it */&lt;/span&gt;

  &lt;span class="comment"&gt;/* Retrieve procedure from closure we just created, and call it,
   * with 3 arguments: itself (t4), the continuation of the call
   * to &amp;quot;interfaces&amp;quot; (t0[2]), and the bytevector buffer (t2).
   */&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;C_proc3&lt;/span&gt;)&lt;/span&gt;C_fast_retrieve_proc&lt;span class="paren3"&gt;(&lt;span class="default"&gt;t4&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;3, t4, &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;C_word*&lt;/span&gt;)&lt;/span&gt;t0&lt;/span&gt;)&lt;/span&gt;&lt;span class="paren3"&gt;[&lt;span class="default"&gt;2&lt;/span&gt;]&lt;/span&gt;, t2&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Our foreign-lambda's wrapper function now consists of two stages.  The first stage first creates a continuation for the usual wrapper function.  Then it calls the garbage collector to clear the stack, after which this wrapper-continuation is invoked.  This wrapper is the second function here, and it corresponds closely to the wrapper function we saw in the &lt;tt&gt;ilen&lt;/tt&gt; example.  However, this wrapper constructs a closure around the C stub function instead of simply calling it.  This closure is then called: &lt;tt&gt;C_fast_retrieve_proc&lt;/tt&gt; simply extracts the function from the closure object we just created, it is cast to a 3-argument procedure type and invoked with the continuation of the &lt;tt&gt;interfaces&lt;/tt&gt; call site.&lt;/p&gt;
&lt;p&gt;You can see how closures are created in CHICKEN.  I will explain this in depth in a future blog post, but the basic approach is pretty clever: the whole thing is one big C expression which stores successive words at the free slots in the allocated space &lt;tt&gt;a&lt;/tt&gt;, while ensuring that after the expression &lt;tt&gt;a&lt;/tt&gt; will point at the next free word.  The dance with &lt;tt&gt;tmp&lt;/tt&gt; ensures that the whole expression which allocates the closure results in the initial value of &lt;tt&gt;a&lt;/tt&gt;.  That initial value was the first free slot before we executed the expression, and afterwards it holds the closure.  Don't worry if this confuses you :)&lt;/p&gt;&lt;a href="#calling-scheme-from-c"&gt;
&lt;h2 id="calling-scheme-from-c"&gt;Calling Scheme from C&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Now, with the basics out of the way, let's do something funkier: instead of calling C from Scheme, we call Scheme from C!  There is a &lt;a href="http://wiki.call-cc.org/man/4/Embedding" class="external"&gt;C API for embedding&lt;/a&gt; CHICKEN in a larger C program, but that's not what you should use when calling Scheme from C code that was itself called from Scheme.&lt;/p&gt;&lt;a href="#the-easy-way"&gt;
&lt;h3 id="the-easy-way"&gt;The &amp;quot;easy&amp;quot; way&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Our little interfaces-listing program has one theoretical flaw: the list of interfaces could be very long (or the names could be long), so we may theoretically run out of stack space.  So, we should avoid allocating unbounded lists directly on the stack without checking for overflow.  Instead, let's pass the allocated objects to a callback procedure which prints the interface, in a &amp;quot;streaming&amp;quot; fashion.&lt;/p&gt;
&lt;p&gt;As I explained before, a regular &lt;tt&gt;foreign-lambda&lt;/tt&gt; uses the C stack in the regular way, it doesn't know about continuations or the Cheney on the MTA garbage collection style, and there's no way to call CHICKEN functions from there, because the GC would &amp;quot;collect&amp;quot; away the C function by &lt;tt&gt;longjmp()&lt;/tt&gt;ing past it.  However, the &lt;tt&gt;foreign-safe-lambda&lt;/tt&gt; has a special provision for that: it can &amp;quot;lock&amp;quot; the current live data by putting a &lt;i&gt;barrier&lt;/i&gt; between this C function and the Scheme code it calls:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;import foreign&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;foreign-declare &lt;span class="string"&gt;&amp;quot;#include &lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;sys/types.h&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;foreign-declare &lt;span class="string"&gt;&amp;quot;#include &lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;sys/socket.h&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;foreign-declare &lt;span class="string"&gt;&amp;quot;#include &lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;ifaddrs.h&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; interfaces
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;foreign-safe-lambda* scheme-object &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;scheme-object receiver&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;C_word len, str, *a;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;struct ifaddrs *ifa, *i;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;if (getifaddrs(&amp;amp;ifa) != 0)&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  C_return(C_SCHEME_UNDEFINED);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;for (i = ifa; i != NULL; i = i-&amp;gt;ifa_next) {&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  len = strlen(i-&amp;gt;ifa_name);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  a = C_alloc(C_SIZEOF_STRING(len));&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  str = C_string(&amp;amp;a, len, i-&amp;gt;ifa_name);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  C_save(str);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  C_callback(receiver, 1);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;}&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;freeifaddrs(ifa);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;C_return(C_SCHEME_UNDEFINED);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;print &lt;span class="string"&gt;&amp;quot;The following interfaces are available: &amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;interfaces print&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This will display the interfaces one line at a time, by using CHICKEN's &lt;tt&gt;print&lt;/tt&gt; procedure as the callback.&lt;/p&gt;
&lt;p&gt;We won't look at the compiled source code for this implementation, because it is identical to the earlier one, except for the changed foreign-lambda body.  The implementation of &lt;tt&gt;C_callback()&lt;/tt&gt; is of interest, but it is a little hairy, so I'll leave it you to &lt;a href="http://code.call-cc.org/cgi-bin/gitweb.cgi?p=chicken-core.git;a=blob;f=runtime.c;h=8d2284d6459d079da8acb83dd9ccbb0c5a66a928;hb=3f195ba73b6faf856bac61155fe52e9a57bc822a#l1919" class="external"&gt;explore it yourself&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The basic idea is rather simple, though: it simply calls &lt;tt&gt;setjmp()&lt;/tt&gt; to establish a new garbage collection trampoline.  This means that the foreign-lambda will always remain on the stack.  The callback is then invoked with a continuation which sets a flag to indicate that the callback has returned normally, in which case its result will be returned to the foreign-lambda.  If it didn't return normally, we arrived at the trampoline because a GC was triggered.  This means the remembered continuation will be re-invoked, like usual.&lt;/p&gt;
&lt;p&gt;However, when the callback did return normally, we can simply return the returned value because the foreign-lambda's stack frame is still available due to the GC barrier we set up.&lt;/p&gt;
&lt;p&gt;The &lt;tt&gt;C_save&lt;/tt&gt; macro simply saves the callback's arguments on a special stack which is read by &lt;tt&gt;C_do_apply&lt;/tt&gt;.  It is also used by &lt;tt&gt;callback_return_continuation&lt;/tt&gt;: it saves the value and triggers a GC to force the returned value into the heap.  That way, we can return it safely to the previous stack frame without it getting clobbered by the next allocation.&lt;/p&gt;&lt;a href="#a-harder-way"&gt;
&lt;h3 id="a-harder-way"&gt;A harder way&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;The above code has another flaw: if the callback raises an exception, the current exception handler will be invoked with the continuation where it was established.  However, that might never return to the callback, which means we have a memory leak on our hands!&lt;/p&gt;
&lt;p&gt;If the callback doesn't return normally, the foreign-lambda will remain on the stack forever.  How do we avoid that little problem? The simplest is of course to wrap the callback's code in &lt;tt&gt;handle-exceptions&lt;/tt&gt; or &lt;tt&gt;condition-case&lt;/tt&gt;.  However, that's no fun at all.&lt;/p&gt;
&lt;p&gt;Besides, in real-world code we want to avoid the overhead of a GC every single time we invoke a C function, so &lt;tt&gt;foreign-safe-lambda&lt;/tt&gt; is not really suitable for functions that are called in a tight loop. In such cases, there is only one way: to deeply integrate in CHICKEN and write a completely native procedure!  Because truly native procedures must call a continuation when they want to pass a result somewhere, we'll have to chop up the functionality into three procedures:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;import foreign&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;use lolevel&lt;/span&gt;)&lt;/span&gt;     &lt;span class="comment"&gt;; For &amp;quot;location&amp;quot;
&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;foreign-declare &lt;span class="string"&gt;&amp;quot;#include &lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;sys/types.h&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;foreign-declare &lt;span class="string"&gt;&amp;quot;#include &lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;sys/socket.h&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;foreign-declare &lt;span class="string"&gt;&amp;quot;#include &lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;ifaddrs.h&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; grab-ifa!
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;foreign-lambda* void &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="paren6"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="string"&gt;&amp;quot;struct ifaddrs&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; ifa&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;if (getifaddrs(ifa) != 0)&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  *ifa = NULL;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; free-ifa!
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;foreign-lambda* void &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="paren6"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="string"&gt;&amp;quot;struct ifaddrs&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; ifa&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;freeifaddrs(*ifa);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; next-ifa
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;foreign-primitive &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="paren6"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="string"&gt;&amp;quot;struct ifaddrs&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; ifa&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;C_word len, str, *a;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;if (*ifa) {&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  len = strlen((*ifa)-&amp;gt;ifa_name);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  a = C_alloc(C_SIZEOF_STRING(len));&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  str = C_string(&amp;amp;a, len, (*ifa)-&amp;gt;ifa_name);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  *ifa = (*ifa)-&amp;gt;ifa_next;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  C_kontinue(C_k, str);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;} else {&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  C_kontinue(C_k, C_SCHEME_FALSE);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;}&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;interfaces&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="comment"&gt;;; Use a pointer which the C function mutates.  We could also
&lt;/span&gt;  &lt;span class="comment"&gt;;; return two values(!) from the &amp;quot;next-ifa&amp;quot; foreign-primitive,
&lt;/span&gt;  &lt;span class="comment"&gt;;; but that complicates the code flow a little bit more.
&lt;/span&gt;  &lt;span class="comment"&gt;;; Sorry about the ugliness of this!
&lt;/span&gt;  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;let-location &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;ifa &lt;span class="paren5"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="string"&gt;&amp;quot;struct ifaddrs&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                 &lt;span class="paren4"&gt;(&lt;span class="default"&gt;i &lt;span class="paren5"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="string"&gt;&amp;quot;struct ifaddrs&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;grab-ifa! &lt;span class="paren4"&gt;(&lt;span class="default"&gt;location ifa&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;unless ifa &lt;span class="paren4"&gt;(&lt;span class="default"&gt;error &lt;span class="string"&gt;&amp;quot;Could not allocate ifaddrs&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;set! i ifa&lt;/span&gt;)&lt;/span&gt;

    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;handle-exceptions exn
      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;begin &lt;span class="paren5"&gt;(&lt;span class="default"&gt;free-ifa! &lt;span class="paren6"&gt;(&lt;span class="default"&gt;location ifa&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;      &lt;span class="comment"&gt;; Prevent memory leak, and
&lt;/span&gt;             &lt;span class="paren5"&gt;(&lt;span class="default"&gt;signal exn&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;                   &lt;span class="comment"&gt;; re-raise the exception
&lt;/span&gt;      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; lp &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;span class="paren6"&gt;(&lt;span class="default"&gt;result &amp;#x27;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
        &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;cond&lt;/span&gt;&lt;/i&gt; &lt;span class="paren6"&gt;(&lt;span class="default"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;next-ifa &lt;span class="paren2"&gt;(&lt;span class="default"&gt;location i&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; =&amp;gt;
               &lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;lambda&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;iface&lt;/span&gt;)&lt;/span&gt;
                 &lt;span class="paren2"&gt;(&lt;span class="default"&gt;lp &lt;span class="paren3"&gt;(&lt;span class="default"&gt;cons iface result&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
              &lt;span class="paren6"&gt;(&lt;span class="default"&gt;else
               &lt;span class="paren1"&gt;(&lt;span class="default"&gt;free-ifa! &lt;span class="paren2"&gt;(&lt;span class="default"&gt;location ifa&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
               result&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="comment"&gt;;; We&amp;#x27;re once again back to constructing a list!
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;print &lt;span class="string"&gt;&amp;quot;The following interfaces are available: &amp;quot;&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;interfaces&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This compiles to something very similar to the code behind a &lt;tt&gt;foreign-safe-lambda&lt;/tt&gt;, but it's obviously going to be a lot bigger due to it being cut up, so I won't duplicate the C code here. Remember, you can always inspect it yourself with &lt;tt&gt;csc -k&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Anyway, this is like the foreign-safe-lambda, but without the implicit GC.  Also, instead of &amp;quot;returning&amp;quot; the value through &lt;tt&gt;C_return()&lt;/tt&gt; we explicitly call the continuation &lt;tt&gt;C_k&lt;/tt&gt; through the &lt;tt&gt;C_kontinue()&lt;/tt&gt; macro, with the value we want to pass on to the &lt;tt&gt;cond&lt;/tt&gt;.  If we wanted to return two values, we could simply use the &lt;tt&gt;C_values()&lt;/tt&gt; macro instead; we're free to do whatever Scheme can do, so we can even return multiple values, as long as the continuation accepts them.&lt;/p&gt;
&lt;p&gt;If an exception happens anywhere in this code, we won't get a memory leak due to the stack being blown up.  However, like in any C code, we need to free up the memory behind the interface addresses.  So we can't really escape our cleanup duty!&lt;/p&gt;
&lt;p&gt;You might think that there's one more problem with &lt;tt&gt;foreign-primitive&lt;/tt&gt;: because it doesn't force a GC before calling the C function, there's still no guarantee about how much space you still have on the stack.  Luckily, CHICKEN has a &lt;tt&gt;C_STACK_RESERVE&lt;/tt&gt;, which defines how much space that is guaranteed to be left on the stack after each &lt;tt&gt;C_demand()&lt;/tt&gt;.  Its value is currently &lt;tt&gt;0x10000&lt;/tt&gt; (i.e., 64 KiB), which means you have some headroom to do basic allocations like we do here, but you shouldn't allocate too many huge objects.  There are ways around that, but unfortunately not using the &amp;quot;official&amp;quot; FFI (that I'm aware of, anyway).  For now we'll stick with the official Scheme API.&lt;/p&gt;&lt;a href="#the-die-hard-way-calling-scheme-closures-from-c"&gt;
&lt;h3 id="the-die-hard-way-calling-scheme-closures-from-c"&gt;The die-hard way: calling Scheme closures from C&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;So far, we've discussed pretty much only things you can find in the &lt;a href="http://wiki.call-cc.org/man/4/Accessing external objects" class="external"&gt;CHICKEN manual's section on the FFI&lt;/a&gt;.  Let's take a look at how we can do things a little differently, and instead of passing the string or &lt;tt&gt;#f&lt;/tt&gt; to a continuation, we pass the callback as a procedure again, just like we did for the &amp;quot;easy&amp;quot; way:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;import foreign&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;use lolevel&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;foreign-declare &lt;span class="string"&gt;&amp;quot;#include &lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;sys/types.h&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;foreign-declare &lt;span class="string"&gt;&amp;quot;#include &lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;sys/socket.h&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;foreign-declare &lt;span class="string"&gt;&amp;quot;#include &lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;ifaddrs.h&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; grab-ifa!
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;foreign-lambda* void &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="paren6"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="string"&gt;&amp;quot;struct ifaddrs&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; ifa&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;if (getifaddrs(ifa) != 0)&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  *ifa = NULL;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; free-ifa!
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;foreign-lambda* void &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="paren6"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="string"&gt;&amp;quot;struct ifaddrs&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; ifa&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;freeifaddrs(*ifa);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; next-ifa
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;foreign-primitive &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="paren6"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="string"&gt;&amp;quot;struct ifaddrs&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; ifa&lt;/span&gt;)&lt;/span&gt;
                      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;scheme-object more&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;scheme-object done&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;C_word len, str, *a;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;if (*ifa) {&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  len = strlen((*ifa)-&amp;gt;ifa_name);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  a = C_alloc(C_SIZEOF_STRING(len));&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  str = C_string(&amp;amp;a, len, (*ifa)-&amp;gt;ifa_name);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  *ifa = (*ifa)-&amp;gt;ifa_next;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  ((C_proc3)C_fast_retrieve_proc(more))(3, more, C_k, str);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="comment"&gt;;; Alternatively:
&lt;/span&gt;    &lt;span class="comment"&gt;;; &amp;quot;  C_save(str); \n&amp;quot;
&lt;/span&gt;    &lt;span class="comment"&gt;;; &amp;quot;  C_do_apply(2, more, C_k); \n&amp;quot;
&lt;/span&gt;    &lt;span class="comment"&gt;;; Or, if we want to call Scheme&amp;#x27;s APPLY directly (slower):
&lt;/span&gt;    &lt;span class="comment"&gt;;; &amp;quot;  C_apply(5, C_SCHEME_UNDEFINED, C_k, more, \n&amp;quot;
&lt;/span&gt;    &lt;span class="comment"&gt;;; &amp;quot;          str, C_SCHEME_END_OF_LIST); \n&amp;quot;
&lt;/span&gt;    &lt;span class="string"&gt;&amp;quot;} else {&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  ((C_proc2)C_fast_retrieve_proc(done))(2, done, C_k);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="comment"&gt;;; Alternatively:
&lt;/span&gt;    &lt;span class="comment"&gt;;; &amp;quot;  C_do_apply(0, done, C_k); \n&amp;quot;
&lt;/span&gt;    &lt;span class="comment"&gt;;; Or:
&lt;/span&gt;    &lt;span class="comment"&gt;;; &amp;quot;  C_apply(4, C_SCHEME_UNDEFINED, C_k, done, C_SCHEME_END_OF_LIST);\n&amp;quot;
&lt;/span&gt;    &lt;span class="string"&gt;&amp;quot;}&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;interfaces&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;let-location &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;ifa &lt;span class="paren5"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="string"&gt;&amp;quot;struct ifaddrs&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                 &lt;span class="paren4"&gt;(&lt;span class="default"&gt;i &lt;span class="paren5"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="string"&gt;&amp;quot;struct ifaddrs&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;grab-ifa! &lt;span class="paren4"&gt;(&lt;span class="default"&gt;location ifa&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;unless ifa &lt;span class="paren4"&gt;(&lt;span class="default"&gt;error &lt;span class="string"&gt;&amp;quot;Could not allocate ifaddrs&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;set! i ifa&lt;/span&gt;)&lt;/span&gt;

    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;handle-exceptions exn
      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;begin &lt;span class="paren5"&gt;(&lt;span class="default"&gt;free-ifa! &lt;span class="paren6"&gt;(&lt;span class="default"&gt;location ifa&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
             &lt;span class="paren5"&gt;(&lt;span class="default"&gt;signal exn&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; lp &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;span class="paren6"&gt;(&lt;span class="default"&gt;result &amp;#x27;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
        &lt;span class="paren5"&gt;(&lt;span class="default"&gt;next-ifa &lt;span class="paren6"&gt;(&lt;span class="default"&gt;location i&lt;/span&gt;)&lt;/span&gt;
                  &lt;span class="paren6"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;lambda&lt;/span&gt;&lt;/i&gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;iface&lt;/span&gt;)&lt;/span&gt;               &lt;span class="comment"&gt;; more
&lt;/span&gt;                    &lt;span class="paren1"&gt;(&lt;span class="default"&gt;lp &lt;span class="paren2"&gt;(&lt;span class="default"&gt;cons iface result&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                  &lt;span class="paren6"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;lambda&lt;/span&gt;&lt;/i&gt; &lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt;                    &lt;span class="comment"&gt;; done
&lt;/span&gt;                    &lt;span class="paren1"&gt;(&lt;span class="default"&gt;free-ifa! &lt;span class="paren2"&gt;(&lt;span class="default"&gt;location ifa&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                    result&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;print &lt;span class="string"&gt;&amp;quot;The following interfaces are available: &amp;quot;&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;interfaces&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The magic lies in the expression &lt;tt&gt;((C_proc3)C_fast_retrieve_proc(more))(3, more, C_k, str)&lt;/tt&gt;.  We've seen something like it before in generated C code snippets: First, it extracts the C function pointer from the closure object in &lt;tt&gt;more&lt;/tt&gt;. Then, the function pointer is cast to the correct type; &lt;tt&gt;C_proc3&lt;/tt&gt; refers to a procedure which accepts three arguments.  This excludes the argument count, which actually is the first argument in the call. The next argument is the closure itself, which is needed when the closures has local variables it refers to (like &lt;tt&gt;result&lt;/tt&gt; and &lt;tt&gt;lp&lt;/tt&gt; in the example).  The argument after the closure is its continuation. We just pass on &lt;tt&gt;C_k&lt;/tt&gt;: the final continuation of both &lt;tt&gt;more&lt;/tt&gt; and &lt;tt&gt;done&lt;/tt&gt; is the continuation of &lt;tt&gt;lp&lt;/tt&gt;, which is also the continuation of &lt;tt&gt;next-ifa&lt;/tt&gt;.  Finally, the arguments following the continuation are the values passed as arguments: &lt;tt&gt;iface&lt;/tt&gt; for the &lt;tt&gt;more&lt;/tt&gt; closure.&lt;/p&gt;
&lt;p&gt;The &lt;tt&gt;done&lt;/tt&gt; closure is invoked as &lt;tt&gt;C_proc2&lt;/tt&gt; with only itself and the continuation, but no further arguments.  This corresponds to the fact that &lt;tt&gt;done&lt;/tt&gt; is just a &lt;i&gt;thunk&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;I've shown two alternative ways to call the closure.  The first is to call the closure through the &lt;tt&gt;C_do_apply&lt;/tt&gt; function.  This is basically a dispatcher which checks the argument count and uses the correct &lt;tt&gt;C_proc&amp;lt;n&amp;gt;&lt;/tt&gt; cast and then calls it with the arguments, taken from a temporary stack on which &lt;tt&gt;C_save&lt;/tt&gt; places the arguments.  The &lt;a href="http://code.call-cc.org/cgi-bin/gitweb.cgi?p=chicken-core.git;a=blob;f=runtime.c;h=fd3a3bed69b65dd7139deea4710e5b64c8ce5bcc;hb=HEAD#l6006" class="external"&gt;implementation behind it&lt;/a&gt; is positively insane, and worth checking out for the sheer madness of it.&lt;/p&gt;
&lt;p&gt;The second alternative is to use &lt;tt&gt;C_apply&lt;/tt&gt;, which is the C implementation of Scheme's &lt;tt&gt;apply&lt;/tt&gt; procedure.  It's a bit awkward to call from C, because this procedure is a true Scheme procedure.  That means it accepts an argument count, itself and its continuation and only &lt;i&gt;then&lt;/i&gt; its arguments, which are the closure and the arguments to pass to the closure, with the final argument being a list:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;apply + 1 2 &amp;#x27;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;3 4&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; =&amp;gt; 10&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;In C this would be:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;C_apply&lt;span class="paren1"&gt;(&lt;span class="default"&gt;6, C_SCHEME_UNDEFINED, C_k, C_closure&lt;span class="paren2"&gt;(&lt;span class="default"&gt;&amp;amp;a, 1, C_plus&lt;/span&gt;)&lt;/span&gt;,
        C_fix&lt;span class="paren2"&gt;(&lt;span class="default"&gt;1&lt;/span&gt;)&lt;/span&gt;, C_fix&lt;span class="paren2"&gt;(&lt;span class="default"&gt;2&lt;/span&gt;)&lt;/span&gt;, C_list2&lt;span class="paren2"&gt;(&lt;span class="default"&gt;C_fix&lt;span class="paren3"&gt;(&lt;span class="default"&gt;3&lt;/span&gt;)&lt;/span&gt;, C_fix&lt;span class="paren3"&gt;(&lt;span class="default"&gt;4&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;It also checks its arguments, so if you pass something that's not a list as its final argument, it raises a nice exception:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;import foreign&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;foreign-primitive &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt;
   &lt;span class="string"&gt;&amp;quot;C_word ab[C_SIZEOF_CLOSURE(1)], *a = ab; &lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
   &lt;span class="string"&gt;&amp;quot;C_apply(4, C_SCHEME_UNDEFINED, C_k, &amp;quot;&lt;/span&gt;
   &lt;span class="string"&gt;&amp;quot;        C_closure(&amp;amp;a, 1, (C_word)C_plus), C_fix(1));&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This program prints the following when executed:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; Error: (apply) bad argument type: 1
         Call history:
         test.scm:2: g11         &amp;lt;--&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;And this brings us to our final example, where we go absolutely crazy.&lt;/p&gt;&lt;a href="#the-guru-way-calling-scheme-closures-you-didnt-receive"&gt;
&lt;h3 id="the-guru-way-calling-scheme-closures-you-didnt-receive"&gt;The guru way: Calling Scheme closures you didn't receive&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;You might have noticed that the error message above appears without us passing the &lt;tt&gt;error&lt;/tt&gt; procedure to &lt;tt&gt;+&lt;/tt&gt;, and if you had wrapped the call in an exception handler it would've called its continuation, without us passing it to the procedure.  In some situations you might like to avoid boring the user with passing some procedure to handle some exceptional situation.  Let's see if we can do something like that ourselves!&lt;/p&gt;
&lt;p&gt;It turns out to be pretty easy:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;import foreign&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;use lolevel&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;foreign-declare &lt;span class="string"&gt;&amp;quot;#include &lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;sys/types.h&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;foreign-declare &lt;span class="string"&gt;&amp;quot;#include &lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;sys/socket.h&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;foreign-declare &lt;span class="string"&gt;&amp;quot;#include &lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;ifaddrs.h&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; grab-ifa!
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;foreign-lambda* void &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="paren6"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="string"&gt;&amp;quot;struct ifaddrs&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; ifa&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;if (getifaddrs(ifa) != 0)&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  *ifa = NULL;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; free-ifa!
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;foreign-lambda* void &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="paren6"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="string"&gt;&amp;quot;struct ifaddrs&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; ifa&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;freeifaddrs(*ifa);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;show-iface-name x&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;print x&lt;/span&gt;)&lt;/span&gt;
  #t&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; next-ifa
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;foreign-primitive &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="paren6"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="string"&gt;&amp;quot;struct ifaddrs&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; ifa&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;C_word len, str, *a, show_sym, show_proc;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;if (*ifa) {&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  len = strlen((*ifa)-&amp;gt;ifa_name);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  a = C_alloc(C_SIZEOF_INTERNED_SYMBOL(15) + C_SIZEOF_STRING(len));&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  str = C_string(&amp;amp;a, len, (*ifa)-&amp;gt;ifa_name);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  *ifa = (*ifa)-&amp;gt;ifa_next;&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="comment"&gt;;; The new bit:
&lt;/span&gt;    &lt;span class="string"&gt;&amp;quot;  show_sym = C_intern2(&amp;amp;a, C_text(&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;show-iface-name&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;));&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  show_proc = C_block_item(show_sym, 0);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  ((C_proc3)C_fast_retrieve_proc(show_proc))(3, show_proc, C_k, str);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;} else {&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;  C_kontinue(C_k, C_SCHEME_FALSE);&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="string"&gt;&amp;quot;}&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;interfaces&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;let-location &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;ifa &lt;span class="paren5"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="string"&gt;&amp;quot;struct ifaddrs&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                 &lt;span class="paren4"&gt;(&lt;span class="default"&gt;i &lt;span class="paren5"&gt;(&lt;span class="default"&gt;c-pointer &lt;span class="string"&gt;&amp;quot;struct ifaddrs&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;grab-ifa! &lt;span class="paren4"&gt;(&lt;span class="default"&gt;location ifa&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;unless ifa &lt;span class="paren4"&gt;(&lt;span class="default"&gt;error &lt;span class="string"&gt;&amp;quot;Could not allocate ifaddrs&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;set! i ifa&lt;/span&gt;)&lt;/span&gt;

    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;handle-exceptions exn
      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;begin &lt;span class="paren5"&gt;(&lt;span class="default"&gt;free-ifa! &lt;span class="paren6"&gt;(&lt;span class="default"&gt;location ifa&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
             &lt;span class="paren5"&gt;(&lt;span class="default"&gt;signal exn&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; lp &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt;
        &lt;span class="comment"&gt;;; next-ifa now returns true if it printed an interface and is
&lt;/span&gt;	&lt;span class="comment"&gt;;; ready to get the next one, or false if it reached the end.
&lt;/span&gt;        &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;if&lt;/span&gt;&lt;/i&gt; &lt;span class="paren6"&gt;(&lt;span class="default"&gt;next-ifa &lt;span class="paren1"&gt;(&lt;span class="default"&gt;location i&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
            &lt;span class="paren6"&gt;(&lt;span class="default"&gt;lp&lt;/span&gt;)&lt;/span&gt;
            &lt;span class="paren6"&gt;(&lt;span class="default"&gt;free-ifa! &lt;span class="paren1"&gt;(&lt;span class="default"&gt;location ifa&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;print &lt;span class="string"&gt;&amp;quot;The following interfaces are available: &amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;interfaces&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This uses &lt;tt&gt;C_intern2&lt;/tt&gt; to look up the symbol for &lt;tt&gt;&amp;quot;show-iface-name&amp;quot;&lt;/tt&gt; in the symbol table (or intern it if it didn't exist yet).  We store this in &lt;tt&gt;show_sym&lt;/tt&gt;.  Then, we look at the symbol's first slot, where the value is stored for the global variable identified by the symbol.  The value slot always exists, but if it is undefined, the value is &lt;tt&gt;C_SCHEME_UNDEFINED&lt;/tt&gt;.  Anyway, we assume it's defined and we call it like we did in the example before this one: extract the first slot from the closure and call it.&lt;/p&gt;
&lt;p&gt;This particular example isn't very useful, but the technique can be used to invoke &lt;i&gt;hook&lt;/i&gt; procedures, and in fact the core itself uses it from &lt;tt&gt;barf()&lt;/tt&gt; when it invokes &lt;tt&gt;##sys#error-hook&lt;/tt&gt; to construct and raise an exception when an error situation occurs in the C runtime.&lt;/p&gt;</content>
    <id>tag:more-magic,2014-10-16:/posts/scheme-c-integration.html</id>
    <published>2014-10-16T19:05:25Z</published>
    <title type="text">A (mostly) comprehensive guide to calling C from Scheme and vice versa</title>
    <updated>2014-10-16T19:05:25Z</updated>
    <link href="https://www.more-magic.net/posts/scheme-c-integration.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;One of CHICKEN's coolest features has to be its unique approach to garbage collection.  When someone asked about implementation details (hi, Arthur!), I knew this would make for an interesting blog post. This post is going to be long and technical, so hold on to your hats! Don't worry if you don't get through this in one sitting.&lt;/p&gt;&lt;a href="#prerequisites"&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;There's a whole lot of stuff that we'll need to explain before we get to the actual garbage collector.  CHICKEN's garbage collection (GC) strategy is deeply intertwined with its compilation strategy, so I'll start by explaining the basics of that, before we can continue (pun intended) with the actual GC stuff.&lt;/p&gt;&lt;a href="#a-short-introduction-to-continuation-passing-style"&gt;
&lt;h3 id="a-short-introduction-to-continuation-passing-style"&gt;A short introduction to continuation-passing style&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;The essence of CHICKEN's design is a simple yet brilliant idea by Henry Baker, described in his paper &lt;i&gt;&lt;a href="http://home.pipeline.com/~hbaker1/CheneyMTA.html" class="external"&gt;CONS Should Not CONS Its Arguments, Part II: Cheney on the M.T.A.&lt;/a&gt;&lt;/i&gt;.  The paper is pretty terse, but it's well-written, so I recommend you check it out before reading on.  If you grok everything in it, you probably won't get much out of my blog post and you can stop reading now.  If you don't grok it, it's probably a good idea to re-read it again later.&lt;/p&gt;
&lt;p&gt;Baker's approach assumes a Scheme to C compiler which uses &lt;i&gt;continuation-passing style (CPS)&lt;/i&gt; as an internal representation. This is the quintessential internal representation of Scheme programs, going all the way back to the first proper Scheme compiler, &lt;i&gt;&lt;a href="http://repository.readscheme.org/ftp/papers/ai-lab-pubs/AITR-474.pdf" class="external"&gt;RABBIT&lt;/a&gt;&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;Guy L. Steele (RABBIT's author) did not use CPS to make garbage collection easier.  In fact, RABBIT had no GC of its own, as it relied on MacLISP as a target language (which compiled to PDP-10 machine code and had its own garbage collector).  Instead, continuations allowed for efficient implementation of nested procedure calls.  It eliminated the need for a stack to keep track of this nesting by simply returning the &amp;quot;next thing to do&amp;quot; to a driver loop which took care of invoking it.  This made it possible to write down iterative algorithms as a recursive function without causing a stack overflow.&lt;/p&gt;
&lt;p&gt;Let's consider a silly program which sums up all the numbers in a list, and shows the result multiplied by two:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;calculate-sum lst result&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;if&lt;/span&gt;&lt;/i&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;null? lst&lt;/span&gt;)&lt;/span&gt;
      result
      &lt;span class="paren3"&gt;(&lt;span class="default"&gt;calculate-sum &lt;span class="paren4"&gt;(&lt;span class="default"&gt;cdr lst&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;+ result &lt;span class="paren5"&gt;(&lt;span class="default"&gt;car lst&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;show-sum lst&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;print-number &lt;span class="paren3"&gt;(&lt;span class="default"&gt;* 2 &lt;span class="paren4"&gt;(&lt;span class="default"&gt;calculate-sum lst 0&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;show-sum &amp;#x27;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;1 2 3&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;A naive compilation to C would look something like this (brutally simplified):&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="symbol"&gt;void&lt;/span&gt; entry_point&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  toplevel&lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt;;
  exit&lt;span class="paren2"&gt;(&lt;span class="default"&gt;0&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* Assume exit(1) is explicitly called elsewhere in case of error. */&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;

&lt;span class="symbol"&gt;void&lt;/span&gt; toplevel&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  &lt;span class="comment"&gt;/* SCM_make_list() &amp;amp; SCM_fx() allocate memory.  &amp;quot;fx&amp;quot; stands for &amp;quot;fixnum&amp;quot;. */&lt;/span&gt;
  SCM_obj *lst = SCM_make_list&lt;span class="paren2"&gt;(&lt;span class="default"&gt;3, SCM_fx&lt;span class="paren3"&gt;(&lt;span class="default"&gt;1&lt;/span&gt;)&lt;/span&gt;, SCM_fx&lt;span class="paren3"&gt;(&lt;span class="default"&gt;2&lt;/span&gt;)&lt;/span&gt;, SCM_fx&lt;span class="paren3"&gt;(&lt;span class="default"&gt;3&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
  show_sum&lt;span class="paren2"&gt;(&lt;span class="default"&gt;lst&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;

SCM_obj* show_sum&lt;span class="paren1"&gt;(&lt;span class="default"&gt;SCM_obj *lst&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  SCM_obj result = calculate_sum&lt;span class="paren2"&gt;(&lt;span class="default"&gt;lst, SCM_fx&lt;span class="paren3"&gt;(&lt;span class="default"&gt;0&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
  &lt;span class="comment"&gt;/* SCM_fx_times() allocates memory. */&lt;/span&gt;
  &lt;span class="symbol"&gt;return&lt;/span&gt; SCM_print_number&lt;span class="paren2"&gt;(&lt;span class="default"&gt;SCM_fx_times&lt;span class="paren3"&gt;(&lt;span class="default"&gt;SCM_fx&lt;span class="paren4"&gt;(&lt;span class="default"&gt;2&lt;/span&gt;)&lt;/span&gt;, result&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;

SCM_obj* calculate_sum&lt;span class="paren1"&gt;(&lt;span class="default"&gt;SCM_obj *lst, SCM_obj *result&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;lst == SCM_NIL&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt; &lt;span class="comment"&gt;/* Optimised */&lt;/span&gt;
    &lt;span class="symbol"&gt;return&lt;/span&gt; result;
  &lt;/span&gt;}&lt;/span&gt; &lt;span class="symbol"&gt;else&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    &lt;span class="comment"&gt;/* SCM_fx_plus() allocates memory. */&lt;/span&gt;
    SCM_obj *tmp = SCM_cdr&lt;span class="paren3"&gt;(&lt;span class="default"&gt;lst&lt;/span&gt;)&lt;/span&gt;;
    SCM_obj *tmp2 = SCM_fx_plus&lt;span class="paren3"&gt;(&lt;span class="default"&gt;result, SCM_car&lt;span class="paren4"&gt;(&lt;span class="default"&gt;lst&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
    &lt;span class="symbol"&gt;return&lt;/span&gt; calculate_sum&lt;span class="paren3"&gt;(&lt;span class="default"&gt;tmp, tmp2&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* Recur */&lt;/span&gt;
  &lt;/span&gt;}&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;

SCM_obj *SCM_print_number&lt;span class="paren1"&gt;(&lt;span class="default"&gt;SCM_obj *data&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  printf&lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;%d&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;, SCM_fx_to_integer&lt;span class="paren3"&gt;(&lt;span class="default"&gt;data&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
  &lt;span class="symbol"&gt;return&lt;/span&gt; SCM_VOID;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This particular implementation probably can't use a copying garbage collector like CHICKEN uses, because the &lt;tt&gt;SCM_obj&lt;/tt&gt; pointers which store the Scheme objects' locations would all become invalid.  But let's ignore that for now.&lt;/p&gt;
&lt;p&gt;Due to the recursive call in &lt;tt&gt;calculate_sum()&lt;/tt&gt;, the stack just keeps growing, and eventually we'll get a stack overflow if the list is too long.  Steele argued that this is a silly limitation which results in the proliferation of special-purpose &amp;quot;iteration&amp;quot; constructs found in most languages.  Also, he was convinced that this just cramps the programmer's style: we shouldn't have to think about implementation details like the stack size.  In his time people often used &lt;tt&gt;goto&lt;/tt&gt; instead of function calls as a performance hack.  This annoyed him enough &lt;a href="https://dspace.mit.edu/handle/1721.1/5753" class="external"&gt;to write a rant about it&lt;/a&gt;, which should be required reading for all would-be language designers!&lt;/p&gt;
&lt;p&gt;Anyway, a compiler can transparently convert our Scheme program into CPS, which would look something like this after translation to C:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="comment"&gt;/* Set up initial continuation &amp;amp; toplevel call. */&lt;/span&gt;
&lt;span class="symbol"&gt;void&lt;/span&gt; entry_point&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  SCM_cont *cont = SCM_make_cont&lt;span class="paren2"&gt;(&lt;span class="default"&gt;1, &amp;amp;toplevel, SCM_exit_continuation&lt;/span&gt;)&lt;/span&gt;;
  SCM_call *call = SCM_make_call&lt;span class="paren2"&gt;(&lt;span class="default"&gt;0, cont&lt;/span&gt;)&lt;/span&gt;;
  SCM_driver_loop&lt;span class="paren2"&gt;(&lt;span class="default"&gt;call&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;

&lt;span class="symbol"&gt;void&lt;/span&gt; SCM_driver_loop&lt;span class="paren1"&gt;(&lt;span class="default"&gt;SCM_call *call&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  &lt;span class="comment"&gt;/* The trampoline to which every function returns its continuation. */&lt;/span&gt;
  &lt;span class="symbol"&gt;while&lt;/span&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;true&lt;/span&gt;)&lt;/span&gt;
    call = SCM_perform_continuation_call&lt;span class="paren2"&gt;(&lt;span class="default"&gt;call&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;

SCM_call *toplevel&lt;span class="paren1"&gt;(&lt;span class="default"&gt;SCM_cont *cont&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  SCM_cont *next = SCM_make_cont&lt;span class="paren2"&gt;(&lt;span class="default"&gt;1, &amp;amp;show_sum, cont&lt;/span&gt;)&lt;/span&gt;;
  SCM_obj *lst = SCM_make_list&lt;span class="paren2"&gt;(&lt;span class="default"&gt;3, SCM_fx&lt;span class="paren3"&gt;(&lt;span class="default"&gt;1&lt;/span&gt;)&lt;/span&gt;, SCM_fx&lt;span class="paren3"&gt;(&lt;span class="default"&gt;2&lt;/span&gt;)&lt;/span&gt;, SCM_fx&lt;span class="paren3"&gt;(&lt;span class="default"&gt;3&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
  &lt;span class="symbol"&gt;return&lt;/span&gt; SCM_make_call&lt;span class="paren2"&gt;(&lt;span class="default"&gt;1, next, lst&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;

SCM_call *show_sum&lt;span class="paren1"&gt;(&lt;span class="default"&gt;SCM_cont *cont, SCM_obj *lst&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  SCM_cont *next = SCM_make_cont&lt;span class="paren2"&gt;(&lt;span class="default"&gt;1, &amp;amp;show_sum_continued, cont&lt;/span&gt;)&lt;/span&gt;;
  SCM_cont *now = SCM_make_cont&lt;span class="paren2"&gt;(&lt;span class="default"&gt;2, &amp;amp;calculate_sum, next&lt;/span&gt;)&lt;/span&gt;;
  &lt;span class="symbol"&gt;return&lt;/span&gt; SCM_make_call&lt;span class="paren2"&gt;(&lt;span class="default"&gt;2, now, lst, SCM_fx&lt;span class="paren3"&gt;(&lt;span class="default"&gt;0&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;

SCM_call *calculate_sum&lt;span class="paren1"&gt;(&lt;span class="default"&gt;SCM_cont *cont, SCM_obj *lst, SCM_obj *result&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;lst == SCM_NIL&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt; &lt;span class="comment"&gt;/* Optimised */&lt;/span&gt;
    &lt;span class="symbol"&gt;return&lt;/span&gt; SCM_make_call&lt;span class="paren3"&gt;(&lt;span class="default"&gt;1, cont, result&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt; &lt;span class="symbol"&gt;else&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    SCM_obj *tmp = SCM_cdr&lt;span class="paren3"&gt;(&lt;span class="default"&gt;lst&lt;/span&gt;)&lt;/span&gt;;
    SCM_obj *tmp2 = SCM_fx_plus&lt;span class="paren3"&gt;(&lt;span class="default"&gt;result, SCM_car&lt;span class="paren4"&gt;(&lt;span class="default"&gt;lst&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
    SCM_cont *now = SCM_make_cont&lt;span class="paren3"&gt;(&lt;span class="default"&gt;2, &amp;amp;calculate_sum, cont&lt;/span&gt;)&lt;/span&gt;;
    &lt;span class="symbol"&gt;return&lt;/span&gt; SCM_make_call&lt;span class="paren3"&gt;(&lt;span class="default"&gt;2, now, tmp, tmp2&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* &amp;quot;Recur&amp;quot; */&lt;/span&gt;
  &lt;/span&gt;}&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;

SCM_call *show_sum_continued&lt;span class="paren1"&gt;(&lt;span class="default"&gt;SCM_cont *cont, SCM_obj *result&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  SCM_cont *now = SCM_make_cont&lt;span class="paren2"&gt;(&lt;span class="default"&gt;1, &amp;amp;SCM_print_number, cont&lt;/span&gt;)&lt;/span&gt;;
  SCM_obj *tmp = SCM_fx_times&lt;span class="paren2"&gt;(&lt;span class="default"&gt;SCM_fx&lt;span class="paren3"&gt;(&lt;span class="default"&gt;2&lt;/span&gt;)&lt;/span&gt;, result&lt;/span&gt;)&lt;/span&gt;;
  &lt;span class="symbol"&gt;return&lt;/span&gt; SCM_make_call&lt;span class="paren2"&gt;(&lt;span class="default"&gt;1, now, tmp&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;

SCM_call *SCM_print_number&lt;span class="paren1"&gt;(&lt;span class="default"&gt;SCM_cont *cont, SCM_obj *data&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  printf&lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;%d&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;, SCM_fx_to_integer&lt;span class="paren3"&gt;(&lt;span class="default"&gt;data&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
  &lt;span class="symbol"&gt;return&lt;/span&gt; SCM_make_call&lt;span class="paren2"&gt;(&lt;span class="default"&gt;1, cont, SCM_VOID&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;In the above code, there are two new data types: &lt;tt&gt;SCM_cont&lt;/tt&gt; and &lt;tt&gt;SCM_call&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;An &lt;tt&gt;SCM_cont&lt;/tt&gt; represents a Scheme continuation as a C function's address, the number of arguments which it expects (minus one) and another continuation, which indicates where to continue after the C function has finished.  This sounds recursive, but as you can see the very first continuation created by &lt;tt&gt;entry_point()&lt;/tt&gt; is a specially prepared one which will cause the process to exit.&lt;/p&gt;
&lt;p&gt;An &lt;tt&gt;SCM_call&lt;/tt&gt; is returned to the driver loop by every generated C function: this holds a continuation and the arguments with which to invoke it.  &lt;tt&gt;SCM_perform_continuation_call()&lt;/tt&gt; extracts the &lt;tt&gt;SCM_cont&lt;/tt&gt; from the &lt;tt&gt;SCM_call&lt;/tt&gt; and invokes its C function with its continuation and the arguments from the &lt;tt&gt;SCM_call&lt;/tt&gt;.  We won't dwell on the details of its implementation now, but assume this is some magic which just works.&lt;/p&gt;
&lt;p&gt;You'll also note that the &lt;i&gt;primitives&lt;/i&gt; &lt;tt&gt;SCM_car()&lt;/tt&gt;, &lt;tt&gt;SCM_cdr()&lt;/tt&gt;, &lt;tt&gt;SCM_fx_plus()&lt;/tt&gt; and &lt;tt&gt;SCM_fx_times()&lt;/tt&gt; do not accept a continuation. This is a typical optimisation: some primitives can be inlined by the compiler.  However, this is not required: you can make them accept a continuation as well, at the cost of further splintering the C functions into small sections; the &lt;tt&gt;calculate_sum()&lt;/tt&gt; function would be split up into 4 separate functions if we did that.&lt;/p&gt;
&lt;p&gt;Anyway, going back to the big picture we can see that this continuation-based approach consumes a more or less &lt;i&gt;constant&lt;/i&gt; amount of stack space, because each function returns to &lt;tt&gt;driver_loop&lt;/tt&gt;.  Baker's fundamental insight was that the stack is there anyway (and it &lt;i&gt;will&lt;/i&gt; be used by C), and if we don't need it for tracking function call nesting, why not use it for something else?  He proposed to allocate all newly created objects on the stack.  Because the stack would hopefully fit the CPU's cache in its entirety, this could give quite a performance benefit.&lt;/p&gt;&lt;a href="#generational-collection"&gt;
&lt;h3 id="generational-collection"&gt;Generational collection&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;To understand why keeping new data together on the stack can be faster, it's important to know that most objects are quite short-lived.  Most algorithms involve intermediate values, which are accessed quite a bit during a calculation but are no longer needed afterwards.  These values need to be stored somewhere in memory. Normally you would store them together with all other objects in the main heap, which may cause fragmentation of said heap.  Fragmentation means that memory references may cross page boundaries.  This is slow, because it will clear out the CPU's memory cache and may even require swapping it in, if the machine is low on memory.&lt;/p&gt;
&lt;p&gt;On top of that, generating a lot of intermediate values means generating a lot of garbage, which will trigger many GCs during which a lot of these temporary objects will be cleaned up.  However, during these GCs, the remaining longer-lived objects must also be analysed before it can be decided they can stick around.&lt;/p&gt;
&lt;p&gt;This is rather wasteful, and it turns out we can avoid doing so much work by &lt;a href="http://web.media.mit.edu/~lieber/Lieberary/GC/GC.html" class="external"&gt;categorising objects by age&lt;/a&gt;.  Objects that have just been created belong to the first &lt;i&gt;generation&lt;/i&gt; and are stored in their own space (called the &lt;i&gt;nursery&lt;/i&gt; - I'm not kidding!), while those that have survived several GC events belong to older generations, which each have their own space reserved for them.  By keeping different generations separated, you do not have to examine long-lived objects of older generations (which are unlikely to be collected) when collecting garbage in a younger generation.  This can save us a lot of wasted time.&lt;/p&gt;&lt;a href="#managing-data-on-the-stack"&gt;
&lt;h3 id="managing-data-on-the-stack"&gt;Managing data on the stack&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;The Cheney on the M.T.A. algorithm as used by CHICKEN involves only two generations; one generation consisting of newly created objects and the other generation consisting of older objects.  In this algorithm, new objects get immediately promoted (or &lt;i&gt;tenured&lt;/i&gt;) to the old generation after a GC of the nursery (or stack).  Such a GC is called a &lt;i&gt;minor&lt;/i&gt; GC, whereas a GC of the heap is called a &lt;i&gt;major&lt;/i&gt; GC.&lt;/p&gt;
&lt;p&gt;This minor GC is where the novelty lies: objects are allocated on the stack.  You might wonder how that can possibly work, considering the lengths I just went through to explain how CPS conversion gets rid of the stack.  Besides, by returning to the trampoline function whenever a new continuation is invoked, anything you'd store on the stack would need to get purged (that's how the C calling convention works).&lt;/p&gt;
&lt;p&gt;That's right!  The way to make this work is pretty counter-intuitive: we go all the way back to the first Scheme to C conversion I showed you and &lt;i&gt;make it even worse&lt;/i&gt;.  Whenever we want to invoke a continuation, we just call its function.  That means that the example program we started out with would compile to this:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;&lt;span class="comment"&gt;/* Same as before */&lt;/span&gt;
&lt;span class="symbol"&gt;void&lt;/span&gt; entry_point&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  SCM_cont *cont = SCM_make_cont&lt;span class="paren2"&gt;(&lt;span class="default"&gt;1, &amp;amp;toplevel, SCM_exit_continuation&lt;/span&gt;)&lt;/span&gt;;
  SCM_call *call = SCM_make_call&lt;span class="paren2"&gt;(&lt;span class="default"&gt;0, cont&lt;/span&gt;)&lt;/span&gt;;
  SCM_driver_loop&lt;span class="paren2"&gt;(&lt;span class="default"&gt;call&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;

SCM_call *saved_cont_call; &lt;span class="comment"&gt;/* Set by SCM_save_call, read by driver_loop */&lt;/span&gt;
jmp_buf empty_stack_state; &lt;span class="comment"&gt;/* Set by driver_loop, read by minor_GC */&lt;/span&gt;

&lt;span class="symbol"&gt;void&lt;/span&gt; SCM_driver_loop&lt;span class="paren1"&gt;(&lt;span class="default"&gt;SCM_call *call&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  &lt;span class="comment"&gt;/* Save registers (including stack depth and address in this function) */&lt;/span&gt;
  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;setjmp&lt;span class="paren3"&gt;(&lt;span class="default"&gt;empty_stack_state&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    call = saved_cont_call; &lt;span class="comment"&gt;/* Got here via longjmp()? Use stored call */&lt;/span&gt;

  SCM_perform_continuation_call&lt;span class="paren2"&gt;(&lt;span class="default"&gt;call&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;

&lt;span class="symbol"&gt;void&lt;/span&gt; SCM_minor_GC&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  &lt;span class="comment"&gt;/* ...
     Copy live data from stack to heap, which is a minor GC.  Described later.
     ... */&lt;/span&gt;
  longjmp&lt;span class="paren2"&gt;(&lt;span class="default"&gt;empty_stack_state&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* Restore registers (jump back to driver_loop) */&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;

&lt;span class="symbol"&gt;void&lt;/span&gt; toplevel&lt;span class="paren1"&gt;(&lt;span class="default"&gt;SCM_cont *cont&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;!fits_on_stack&lt;span class="paren3"&gt;(&lt;span class="default"&gt;SCM_CONT_SIZE&lt;span class="paren4"&gt;(&lt;span class="default"&gt;0&lt;/span&gt;)&lt;/span&gt; + SCM_CALL_SIZE&lt;span class="paren4"&gt;(&lt;span class="default"&gt;1&lt;/span&gt;)&lt;/span&gt; +
                     SCM_FIXNUM_SIZE * 3 + SCM_PAIR_SIZE * 3&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    SCM_save_call&lt;span class="paren3"&gt;(&lt;span class="default"&gt;0, &amp;amp;toplevel, cont&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* Mutates saved_cont_call */&lt;/span&gt;
    SCM_minor_GC&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* Will re-invoke this function from the start */&lt;/span&gt;
  &lt;/span&gt;}&lt;/span&gt; &lt;span class="symbol"&gt;else&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    &lt;span class="comment"&gt;/* The below stuff will all fit on the stack, as calculated in the if() */&lt;/span&gt;
    SCM_cont *next = SCM_make_cont&lt;span class="paren3"&gt;(&lt;span class="default"&gt;1, &amp;amp;show_sum, cont&lt;/span&gt;)&lt;/span&gt;;
    SCM_obj *lst = SCM_make_list&lt;span class="paren3"&gt;(&lt;span class="default"&gt;3, SCM_fx&lt;span class="paren4"&gt;(&lt;span class="default"&gt;1&lt;/span&gt;)&lt;/span&gt;, SCM_fx&lt;span class="paren4"&gt;(&lt;span class="default"&gt;2&lt;/span&gt;)&lt;/span&gt;, SCM_fx&lt;span class="paren4"&gt;(&lt;span class="default"&gt;3&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
    SCM_call *call = SCM_make_call&lt;span class="paren3"&gt;(&lt;span class="default"&gt;1, next, lst&lt;/span&gt;)&lt;/span&gt;;
    SCM_perform_continuation_call&lt;span class="paren3"&gt;(&lt;span class="default"&gt;call&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;

&lt;span class="symbol"&gt;void&lt;/span&gt; show_sum&lt;span class="paren1"&gt;(&lt;span class="default"&gt;SCM_cont *cont, SCM_obj *lst&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;!fits_on_stack&lt;span class="paren3"&gt;(&lt;span class="default"&gt;SCM_CONT_SIZE&lt;span class="paren4"&gt;(&lt;span class="default"&gt;0&lt;/span&gt;)&lt;/span&gt; * 2 +
                     SCM_CALL_SIZE&lt;span class="paren4"&gt;(&lt;span class="default"&gt;2&lt;/span&gt;)&lt;/span&gt; + SCM_FIXNUM_SIZE&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    SCM_save_call&lt;span class="paren3"&gt;(&lt;span class="default"&gt;1, &amp;amp;show_sum, cont, lst&lt;/span&gt;)&lt;/span&gt;;
    SCM_minor_GC&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt; &lt;span class="symbol"&gt;else&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    SCM_cont *next = SCM_make_cont&lt;span class="paren3"&gt;(&lt;span class="default"&gt;1, &amp;amp;show_sum_continued, cont&lt;/span&gt;)&lt;/span&gt;;
    SCM_cont *now = SCM_make_cont&lt;span class="paren3"&gt;(&lt;span class="default"&gt;2, &amp;amp;calculate_sum, next&lt;/span&gt;)&lt;/span&gt;;
    SCM_call *call = SCM_make_call&lt;span class="paren3"&gt;(&lt;span class="default"&gt;2, now, lst, SCM_fx&lt;span class="paren4"&gt;(&lt;span class="default"&gt;0&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
    SCM_perform_continuation_call&lt;span class="paren3"&gt;(&lt;span class="default"&gt;call&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;

&lt;span class="symbol"&gt;void&lt;/span&gt; calculate_sum&lt;span class="paren1"&gt;(&lt;span class="default"&gt;SCM_cont *cont, SCM_obj *lst, SCM_obj *result&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  &lt;span class="comment"&gt;/* This calculation is overly pessimistic as it counts both arms
     of the if(), but this is acceptable */&lt;/span&gt;
  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;!fits_on_stack&lt;span class="paren3"&gt;(&lt;span class="default"&gt;SCM_CALL_SIZE&lt;span class="paren4"&gt;(&lt;span class="default"&gt;1&lt;/span&gt;)&lt;/span&gt; + SCM_FIXNUM_SIZE +
                     SCM_CONT_SIZE&lt;span class="paren4"&gt;(&lt;span class="default"&gt;1&lt;/span&gt;)&lt;/span&gt; + SCM_CALL_SIZE&lt;span class="paren4"&gt;(&lt;span class="default"&gt;2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    SCM_save_call&lt;span class="paren3"&gt;(&lt;span class="default"&gt;2, &amp;amp;calculate_sum, cont, lst, result&lt;/span&gt;)&lt;/span&gt;;
    SCM_minor_GC&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt; &lt;span class="symbol"&gt;else&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;lst == SCM_NIL&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren3"&gt;{&lt;span class="default"&gt;
      SCM_call *call = SCM_make_call&lt;span class="paren4"&gt;(&lt;span class="default"&gt;1, cont, result&lt;/span&gt;)&lt;/span&gt;;
      SCM_perform_continuation_call&lt;span class="paren4"&gt;(&lt;span class="default"&gt;call&lt;/span&gt;)&lt;/span&gt;;
    &lt;/span&gt;}&lt;/span&gt; &lt;span class="symbol"&gt;else&lt;/span&gt; &lt;span class="paren3"&gt;{&lt;span class="default"&gt;
      SCM_obj *tmp = SCM_cdr&lt;span class="paren4"&gt;(&lt;span class="default"&gt;lst&lt;/span&gt;)&lt;/span&gt;;
      SCM_obj *tmp2 = SCM_fx_plus&lt;span class="paren4"&gt;(&lt;span class="default"&gt;result, SCM_car&lt;span class="paren5"&gt;(&lt;span class="default"&gt;lst&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
      SCM_cont *now = SCM_make_cont&lt;span class="paren4"&gt;(&lt;span class="default"&gt;2, &amp;amp;calculate_sum, cont&lt;/span&gt;)&lt;/span&gt;;
      SCM_call *call = SCM_make_call&lt;span class="paren4"&gt;(&lt;span class="default"&gt;2, now, tmp, tmp2&lt;/span&gt;)&lt;/span&gt;;
      SCM_perform_continuation_call&lt;span class="paren4"&gt;(&lt;span class="default"&gt;call&lt;/span&gt;)&lt;/span&gt;; &lt;span class="comment"&gt;/* &amp;quot;Recur&amp;quot; */&lt;/span&gt;
    &lt;/span&gt;}&lt;/span&gt;
  &lt;/span&gt;}&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;

&lt;span class="symbol"&gt;void&lt;/span&gt; show_sum_continued&lt;span class="paren1"&gt;(&lt;span class="default"&gt;SCM_cont *cont, SCM_obj *result&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;!fits_on_stack&lt;span class="paren3"&gt;(&lt;span class="default"&gt;SCM_CONT_SIZE&lt;span class="paren4"&gt;(&lt;span class="default"&gt;1&lt;/span&gt;)&lt;/span&gt; + SCM_CALL_SIZE&lt;span class="paren4"&gt;(&lt;span class="default"&gt;1&lt;/span&gt;)&lt;/span&gt; + SCM_FIXNUM_SIZE&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    SCM_save_call&lt;span class="paren3"&gt;(&lt;span class="default"&gt;1, &amp;amp;show_sum_continued, cont, result&lt;/span&gt;)&lt;/span&gt;;
    SCM_minor_GC&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt; &lt;span class="symbol"&gt;else&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    SCM_cont *now = SCM_make_cont&lt;span class="paren3"&gt;(&lt;span class="default"&gt;1, &amp;amp;SCM_print_number, cont&lt;/span&gt;)&lt;/span&gt;;
    SCM_obj *tmp = SCM_fx_times&lt;span class="paren3"&gt;(&lt;span class="default"&gt;SCM_fx&lt;span class="paren4"&gt;(&lt;span class="default"&gt;2&lt;/span&gt;)&lt;/span&gt;, result&lt;/span&gt;)&lt;/span&gt;;
    SCM_call *call = SCM_make_call&lt;span class="paren3"&gt;(&lt;span class="default"&gt;1, now, tmp&lt;/span&gt;)&lt;/span&gt;;
    SCM_perform_continuation_call&lt;span class="paren3"&gt;(&lt;span class="default"&gt;call&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;

&lt;span class="symbol"&gt;void&lt;/span&gt; SCM_print_number&lt;span class="paren1"&gt;(&lt;span class="default"&gt;SCM_cont *cont, SCM_obj *data&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;!fits_on_stack&lt;span class="paren3"&gt;(&lt;span class="default"&gt;SCM_CALL_SIZE&lt;span class="paren4"&gt;(&lt;span class="default"&gt;1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    SCM_save_call&lt;span class="paren3"&gt;(&lt;span class="default"&gt;1, &amp;amp;show_sum_continued, cont, data&lt;/span&gt;)&lt;/span&gt;;
    SCM_minor_GC&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt; &lt;span class="symbol"&gt;else&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    printf&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;%d&lt;/span&gt;&lt;span class="string"&gt;\n&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;, SCM_fx_to_integer&lt;span class="paren4"&gt;(&lt;span class="default"&gt;data&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
    SCM_call *call = SCM_make_call&lt;span class="paren3"&gt;(&lt;span class="default"&gt;1, cont, SCM_VOID&lt;/span&gt;)&lt;/span&gt;;
    SCM_perform_continuation_call&lt;span class="paren3"&gt;(&lt;span class="default"&gt;call&lt;/span&gt;)&lt;/span&gt;;
  &lt;/span&gt;}&lt;/span&gt;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Whew! This program is quite a bit longer, but it isn't that different from the second program I showed you.  The main change is that none of the continuation functions return anything.  In fact, these functions, like Charlie in the M.T.A. song, &lt;i&gt;never return&lt;/i&gt;.  In the earlier version every function ended with a &lt;tt&gt;return&lt;/tt&gt; statement, now they end with an invocation of &lt;tt&gt;SCM_perform_continuation_call()&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;To make things worse, allocating functions now also use &lt;tt&gt;alloca()&lt;/tt&gt; to place objects on the stack.  That means that the stack just keeps filling up like the first compilation I showed you, so we're back to where we started!  However, this program is a lot longer due to one important thing: At the start of each continuation function we first check to see if there's enough space left on the stack to accommodate the objects this function will allocate.&lt;/p&gt;
&lt;p&gt;If there's not enough space, we re-create the &lt;tt&gt;SCM_call&lt;/tt&gt; with which this continuation function was invoked using &lt;tt&gt;SCM_save_call()&lt;/tt&gt;. This differs from &lt;tt&gt;SCM_make_call()&lt;/tt&gt; in that it will not allocate on the stack, but will use a separate area to set aside the call object. The pointer to that area is stored in &lt;tt&gt;saved_cont_call&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;&lt;tt&gt;SCM_save_call()&lt;/tt&gt; can't allocate on the stack for a few reasons: The first and most obvious reason is that the saved call wouldn't fit on the stack because we just concluded it is already full.  Second, the arguments to the call must be kept around even when the stack is blown away after the GC has finished.  Third, this stored call contains the &amp;quot;tip&amp;quot; of the iceberg of live data from which the GC will start its trace.  This is described in the next section.&lt;/p&gt;
&lt;p&gt;After the minor GC has finished, we can jump back to the trampoline again.  We use the &lt;tt&gt;setjmp()&lt;/tt&gt; and &lt;tt&gt;longjmp()&lt;/tt&gt; functions for that. When the first call to &lt;tt&gt;SCM_driver_loop()&lt;/tt&gt; is made, it will call &lt;tt&gt;setjmp()&lt;/tt&gt; to save all the CPU's registers to a buffer.  This includes the stack and instruction pointers.  Then, when the minor GC finishes, it calls &lt;tt&gt;longjmp()&lt;/tt&gt; to restore those registers.  Because the stack and instruction pointer are restored, this means execution &amp;quot;restarts&amp;quot; at the place in &lt;tt&gt;driver_loop()&lt;/tt&gt; where &lt;tt&gt;setjmp()&lt;/tt&gt; was invoked.  The &lt;tt&gt;setjmp()&lt;/tt&gt; then returns &lt;i&gt;again&lt;/i&gt;, but now with a nonzero value (it was zero the first time).  The return value is checked and the call is fetched from the special save area to get back to where we were just before we performed the GC.&lt;/p&gt;
&lt;p&gt;This is half the magic, so please make sure you understand this part!&lt;/p&gt;&lt;a href="#the-minor-gc"&gt;
&lt;h2 id="the-minor-gc"&gt;The minor GC&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;The long story above served to set up all the context you need to know to dive into the GC itself, so let's take a closer look at it.&lt;/p&gt;&lt;a href="#picking-the-live-data-from-the-stack"&gt;
&lt;h3 id="picking-the-live-data-from-the-stack"&gt;Picking the &amp;quot;live&amp;quot; data from the stack&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;As we've seen, the GC is invoked when the stack has completely filled up.  At this point, the stack is a complete mess: it has many stack frames from all the function calls that happened between the previous GC and now.  These stack frames consist of return addresses for the C function calls (which we're not even using), stack-allocated C data (which we don't need) and somewhere among that mess there are some Scheme objects.  These objects themselves also belong to two separate categories: the &amp;quot;garbage&amp;quot; and the data that's still being used and needs to be kept around (the so-called &lt;i&gt;live&lt;/i&gt; data).  How on earth are we going to pick only the interesting bits from that mess?&lt;/p&gt;
&lt;p&gt;Like I said before, the saved call contains the &amp;quot;tip of the iceberg&amp;quot; of live data.  It turns out this is all we need to get at every single object which is reachable to the program.  All you need to do is follow the pointers to the arguments and the continuation stored in the call.  For each of these objects, you copy them to the heap and if they are compound objects you follow all the pointers to the objects stored within them, and so on.  Let's take a look at a graphical representation of how this works.  In the picture below I show the situation where a GC is triggered just after the second invocation of &lt;tt&gt;calculate-sum&lt;/tt&gt; (i.e., the first recursive call of itself, with the list &lt;tt&gt;'(2 3)&lt;/tt&gt;):&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/minor-GC.svg" /&gt;&lt;/p&gt;
&lt;p&gt;After the initial shock from seeing this cosmic horror has worn off, let's take a closer look.  It's like a box of tangled cords: if you take the time to carefully untangle them, it's easy, but if you try to do it all at once, it'll leave you overwhelmed.  Luckily, I'm going to talk you through it.  (by the way: this is an SVG so you can zoom in on details as far as you like using your browser's zooming functionality).&lt;/p&gt;
&lt;p&gt;Let's start with the big picture: On the left you see the stack, on the right the heap &lt;i&gt;after copying&lt;/i&gt; and in the bottom centre there's a small area of statically allocated objects, which are not subject to GC.  To get your bearings, check the left margin of the diagram.  I have attempted to visualise C stack frames by writing each function's name above a line leading to the bottom of its frame.&lt;/p&gt;
&lt;p&gt;Let's look at the most recently called function, at the top of the stack.  This is the function which initiated the minor GC: the second call to &lt;tt&gt;calculate_sum()&lt;/tt&gt;.  The shaded area shows the pointers set aside by &lt;tt&gt;SCM_save_call()&lt;/tt&gt;, which form the tip of the iceberg of live data.  More on that later.&lt;/p&gt;
&lt;p&gt;The next frame belongs to the first call to &lt;tt&gt;calculate_sum()&lt;/tt&gt;.  It has allocated a few things on the stack. The topmost element on the stack is the last thing that's allocated due to the way the stack grows upwards in this picture.  This is a pointer to an &lt;tt&gt;SCM_call&lt;/tt&gt; object, marked with &amp;quot;&lt;tt&gt;[call]&lt;/tt&gt;&amp;quot;, which is the name of the variable which is stored there.  If you go back to the implementation of &lt;tt&gt;calculate_sum()&lt;/tt&gt;, you can see that the last thing it does is allocate an &lt;tt&gt;SCM_call&lt;/tt&gt;, and store its pointer in &lt;tt&gt;call&lt;/tt&gt;.  The object itself just precedes the variable on the stack, and is marked with a thick white border to group together the machine words from which it is composed.  From &lt;i&gt;bottom to top&lt;/i&gt;, these are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A tag which indicates that this is a call containing 2 arguments,&lt;/li&gt;
&lt;li&gt;a pointer to an &lt;tt&gt;SCM_cont&lt;/tt&gt; object (taken from the &lt;tt&gt;now&lt;/tt&gt; variable),&lt;/li&gt;
&lt;li&gt;a pointer to an &lt;tt&gt;SCM_obj&lt;/tt&gt; object (the cdr of &lt;tt&gt;lst&lt;/tt&gt;, taken from &lt;tt&gt;tmp&lt;/tt&gt;) and&lt;/li&gt;
&lt;li&gt;a pointer to an &lt;tt&gt;SCM_obj&lt;/tt&gt; object (a fixnum, taken from &lt;tt&gt;tmp2&lt;/tt&gt;).&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Other compound objects are indicated in the same way.&lt;/p&gt;
&lt;p&gt;You'll also have noticed the green, white and dashed arcs with arrow tips.  These connect pointers to their target addresses.  The dashed ones on the right hand side of the stack indicate pointers that are used for local variables in C functions or &lt;tt&gt;SCM_call&lt;/tt&gt; objects. These pointers are unimportant to the garbage collector.  The ones on the left hand side of the stack are pointers from Scheme objects to other Scheme objects.  These &lt;i&gt;are&lt;/i&gt; important to the GC.  The topmost pointer inside the call object we just looked at has a big dashed curve all the way down to the cdr of &lt;tt&gt;lst&lt;/tt&gt;, and the one below it points at the value of &lt;tt&gt;result&lt;/tt&gt;, which is the fixnum &lt;tt&gt;1&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;If you look further down the stack, you'll see the &lt;tt&gt;show_sum&lt;/tt&gt; procedure which doesn't really allocate much: an &lt;tt&gt;SCM_call&lt;/tt&gt;, the initial intermediate result (fixnum &lt;tt&gt;0&lt;/tt&gt;), and two continuations (&lt;tt&gt;next&lt;/tt&gt; and &lt;tt&gt;now&lt;/tt&gt; in the C code).  The bulk of the allocation happens in &lt;tt&gt;toplevel&lt;/tt&gt;, which contains the call to &lt;tt&gt;show_sum&lt;/tt&gt; and allocates a list structure.  This is on the stack in reverse order: first the pair &lt;tt&gt;X = (3 . ())&lt;/tt&gt;, then the pair &lt;tt&gt;Y = (2 . &amp;lt;X&amp;gt;)&lt;/tt&gt; and the pair &lt;tt&gt;Z = (1 . &amp;lt;Y&amp;gt;)&lt;/tt&gt;.  The &lt;tt&gt;()&lt;/tt&gt; is stored as &lt;tt&gt;SCM_NIL&lt;/tt&gt; in the static area, to which the &lt;tt&gt;cdr&lt;/tt&gt; of the bottom-most pair object on the stack points, which is represented by a long green line which swoops down to the static area.&lt;/p&gt;&lt;a href="#copying-the-live-data-to-the-heap"&gt;
&lt;h3 id="copying-the-live-data-to-the-heap"&gt;Copying the live data to the heap&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;The green lines represent links from the saved call to the live data which we need to copy.  You can consider the colour green &amp;quot;contagious&amp;quot;: imagine everything is white initially, except for the saved call.  Then, each line starting at the pointers of the call are painted green.  The target object to which a line leads is also painted green.  Then, we recursively follow lines from pointers in that object and paint those green, etc.  The objects that were already in the heap or the static area are not traversed, so they stay white.&lt;/p&gt;
&lt;p&gt;When an object is painted green, it is also copied to the heap, which is represented by a yellow line.  The object is then &lt;i&gt;overwritten&lt;/i&gt; by a special object which indicates that this object has been moved to the heap.  This special object contains a &lt;i&gt;forwarding pointer&lt;/i&gt; which indicates the new location of the object.  This is useful when you have two objects which point to the same other object, like for example in this code:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;a &lt;span class="paren4"&gt;(&lt;span class="default"&gt;list 3 2 1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren3"&gt;(&lt;span class="default"&gt;b &lt;span class="paren4"&gt;(&lt;span class="default"&gt;cons 4 a&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren3"&gt;(&lt;span class="default"&gt;c &lt;span class="paren4"&gt;(&lt;span class="default"&gt;cons 4 a&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
  ...&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Here you have two lists &lt;tt&gt;(4 3 2 1)&lt;/tt&gt; which share a common tail.  If both lists are live at the moment of GC, we don't want to copy this tail twice, because that would result in it being split into two distinct objects.  Then, a &lt;tt&gt;set-car!&lt;/tt&gt; on &lt;tt&gt;a&lt;/tt&gt; might only be reflected in &lt;tt&gt;b&lt;/tt&gt; but not &lt;tt&gt;c&lt;/tt&gt;, for example.  The forwarding pointers prevent this from happening by simply adjusting a copied object's constituent objects to point to their new locations. Finally, after all data has been copied, all the newly copied objects are checked again for references to objects which may have been relocated after the object was copied.&lt;/p&gt;
&lt;p&gt;The precise algorithm that performs this operation is very clever.  It requires only two pointers and a &lt;tt&gt;while&lt;/tt&gt; loop, but it still handles cyclic data structures correctly.  The idea is that you do the copying I described above in a breadth-first way: you only copy the objects stored in the saved call (without touching their pointers).  Next, you loop from the start of the heap to the end, looking at each object in turn (initially, those are the objects we just copied).  For these objects, you check their components, and see whether they exist in the heap or in the stack.  If they exist in the stack, you copy them over to the end of the heap (again, without touching their pointers). Because they are appended to the heap, the end pointer gets moved to the end of the last object, so the &lt;tt&gt;while&lt;/tt&gt; loop will also take the newly copied objects into consideration.  When you reach the end of the heap, you're done.  In C, that would look something like this:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight c-language"&gt;SCM_obj *slot;
&lt;span class="symbol"&gt;int&lt;/span&gt; i, bytes_copied;
&lt;span class="symbol"&gt;char&lt;/span&gt; *scan_start = heap_start;

&lt;span class="symbol"&gt;for&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;i = 0; i &amp;lt; saved_object_count&lt;span class="paren2"&gt;(&lt;span class="default"&gt;saved_call&lt;/span&gt;)&lt;/span&gt;; ++i&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  obj = get_saved_object&lt;span class="paren2"&gt;(&lt;span class="default"&gt;saved_call, i&lt;/span&gt;)&lt;/span&gt;;
  &lt;span class="comment"&gt;/* copy_object() is called &amp;quot;mark()&amp;quot; in CHICKEN.
     It also set up a forwarding pointer at the original location */&lt;/span&gt;
  bytes_copied = copy_object&lt;span class="paren2"&gt;(&lt;span class="default"&gt;obj, heap_end&lt;/span&gt;)&lt;/span&gt;;
  heap_end += bytes_copied;
&lt;/span&gt;}&lt;/span&gt;

&lt;span class="symbol"&gt;while&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;scan_start &amp;lt; heap_end&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt;
  obj = &lt;span class="paren2"&gt;(&lt;span class="default"&gt;SCM_obj *&lt;/span&gt;)&lt;/span&gt;scan_start;
  &lt;span class="symbol"&gt;for&lt;/span&gt;&lt;span class="paren2"&gt;(&lt;span class="default"&gt;i = 0; i &amp;lt; object_size&lt;span class="paren3"&gt;(&lt;span class="default"&gt;obj&lt;/span&gt;)&lt;/span&gt;; ++i&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;
    slot = get_slot&lt;span class="paren3"&gt;(&lt;span class="default"&gt;obj, i&lt;/span&gt;)&lt;/span&gt;;
    &lt;span class="comment"&gt;/* Nothing needs to be done if it&amp;#x27;s in the heap or static area */&lt;/span&gt;
    &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;exists_in_stack&lt;span class="paren4"&gt;(&lt;span class="default"&gt;slot&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren3"&gt;{&lt;span class="default"&gt;
      &lt;span class="symbol"&gt;if&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;is_forwarding_ptr&lt;span class="paren5"&gt;(&lt;span class="default"&gt;slot&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;{&lt;span class="default"&gt;
        set_slot&lt;span class="paren5"&gt;(&lt;span class="default"&gt;obj, i, forwarding_ptr_target&lt;span class="paren6"&gt;(&lt;span class="default"&gt;slot&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;;
      &lt;/span&gt;}&lt;/span&gt; &lt;span class="symbol"&gt;else&lt;/span&gt; &lt;span class="paren4"&gt;{&lt;span class="default"&gt;
        bytes_copied = copy_object&lt;span class="paren5"&gt;(&lt;span class="default"&gt;slot, heap_end&lt;/span&gt;)&lt;/span&gt;;
        set_slot&lt;span class="paren5"&gt;(&lt;span class="default"&gt;obj, i, heap_end&lt;/span&gt;)&lt;/span&gt;;
        heap_end += bytes_copied;
      &lt;/span&gt;}&lt;/span&gt;
    &lt;/span&gt;}&lt;/span&gt;
  &lt;/span&gt;}&lt;/span&gt;
  scan_start += object_size&lt;span class="paren2"&gt;(&lt;span class="default"&gt;obj&lt;/span&gt;)&lt;/span&gt;;
&lt;/span&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This algorithm is the heart of our garbage collector.  You can find it in &lt;tt&gt;runtime.c&lt;/tt&gt; in the CHICKEN sources in &lt;tt&gt;C_reclaim()&lt;/tt&gt;, under the &lt;tt&gt;rescan:&lt;/tt&gt; label.  The algorithm was &lt;a href="http://people.cs.umass.edu/~emery/classes/cmpsci691s-fall2004/papers/p677-cheney.pdf" class="external"&gt;invented in 1970 by C.J. Cheney&lt;/a&gt;, and is still used in the most &amp;quot;state of the art&amp;quot; implementations.  Now you know why Henry Baker's paper is called &amp;quot;Cheney on the M.T.A.&amp;quot; :)&lt;/p&gt;
&lt;p&gt;After the data has been copied to the heap, the &lt;tt&gt;longjmp()&lt;/tt&gt; in &lt;tt&gt;minor_GC()&lt;/tt&gt; causes everything on the stack to be blown away.  Then, the top stack frame is recreated from the saved call.  This is illustrated below:&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/after-minor-GC.svg" /&gt;&lt;/p&gt;
&lt;p&gt;Everything in the shaded red area below the stack frame for &lt;tt&gt;driver_loop()&lt;/tt&gt; is now unreachable because there are no more pointers from live data pointing into this region of the stack.  Any live Scheme objects allocated here would have been copied to the heap, and all pointers which pointed there relayed to this new copy. Unfortunately, this stale copy of the data will permanently stick around on the stack, which means this data is forever &lt;i&gt;irreclaimable&lt;/i&gt;.  This means it is important that the entry point should consume as little stack space as possible.&lt;/p&gt;&lt;a href="#the-major-gc"&gt;
&lt;h2 id="the-major-gc"&gt;The major GC&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;You might be wondering how garbage on the heap is collected.  That's what the major GC is for.  CHICKEN initially only allocates a small heap area.  The heap consists of two halves: a &lt;i&gt;fromspace&lt;/i&gt; and a &lt;i&gt;tospace&lt;/i&gt;.  The fromspace is the heap as we've seen it so far: in normal usage, this is the part that's used.  The tospace is always empty.&lt;/p&gt;
&lt;p&gt;When a minor GC is copying data from the stack to the fromspace, it may cause the fromspace to fill up.  That's when a major GC is triggered: the data in the fromspace is copied to the tospace using Cheney's algorithm.  Afterwards, the areas are &lt;i&gt;flipped&lt;/i&gt;: the old fromspace is now called tospace and the old tospace is now called fromspace.&lt;/p&gt;
&lt;p&gt;During a major GC, we have a slightly larger set of live data.  It is not just the data from the saved call, because that's only the stuff directly used by the currently running continuation.  We also need to consider global variables and literal objects compiled into the program, for example.  These sorts of objects are also considered live data.  Aside from this, a major collection is performed the same way as a minor collection.&lt;/p&gt;
&lt;p&gt;The smart reader might have noticed a small problem here: what if the amount of garbage cleaned up is less than the data on the stack? Then, the stack data can't be copied to the new heap because it simply is too small.  Well, this is when a third GC mode is triggered: a &lt;i&gt;reallocating GC&lt;/i&gt;.  This causes a new heap to be allocated, twice as big as the current heap.  This is also split in from- and tospace. Then, Cheney's algorithm is performed on the old heap's fromspace, using one half of the new heap as tospace.  When it's finished, the new tospace is called fromspace, and the other half of the new heap is called tospace.  Then, the old heap is de-allocated.&lt;/p&gt;&lt;a href="#some-practical-notes"&gt;
&lt;h2 id="some-practical-notes"&gt;Some practical notes&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;The above situation is a pretty rough sketch of the way the GC works in CHICKEN.  Many details have been omitted, and the actual implementation is extremely hairy.  Below I'll briefly mention how a few important things are implemented.&lt;/p&gt;&lt;a href="#object-representation"&gt;
&lt;h3 id="object-representation"&gt;Object representation&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;You might have noticed that the stack grows pretty quickly in the CPS-converted C code I showed you.  That's because the &lt;tt&gt;SCM_obj&lt;/tt&gt; representation requires allocating every object and storing a pointer to it, so that's a minimum of two machine words per object.&lt;/p&gt;
&lt;p&gt;CHICKEN avoids this overhead for small, often-used objects like characters, booleans and fixnums.  It ensures all allocated objects are word-aligned, so all pointers to objects have their lower bits set to zero.  This means you can easily see whether something is a pointer to an object or something else.&lt;/p&gt;
&lt;p&gt;All objects in CHICKEN are represented by a &lt;tt&gt;C_word&lt;/tt&gt; type, which is the size of a machine word.  So-called &lt;i&gt;immediate&lt;/i&gt; values are stored directly inside the machine word, with nonzero lower bits. Non-immediate values are cast to a pointer type to a C structure which contains the type tag and bits like I did in the example.&lt;/p&gt;
&lt;p&gt;Calls are not represented by objects in CHICKEN.  Instead, the C function is simply invoked directly from the continuation's caller. Continuations are represented as any other object.  For didactic reasons, I used a separate C type to distinguish it from &lt;tt&gt;SCM_obj&lt;/tt&gt;, but in Scheme continuations can be &lt;i&gt;reified&lt;/i&gt; as first-class objects, so they shouldn't be represented in a fundamentally different way.&lt;/p&gt;&lt;a href="#closures"&gt;
&lt;h3 id="closures"&gt;Closures&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;You might be wondering how closures are implemented, because this hasn't been discussed at all. The answer is pretty simple: in the example code, a &lt;tt&gt;SCM_call&lt;/tt&gt; object stored a plain C function's address.  Instead, we could store a closure instead: this is a new type of object which holds a C function plus its local variables. Each C function receives this closure as an extra argument (in the CHICKEN sources this is called &lt;tt&gt;self&lt;/tt&gt;).  When it needs to access a closed-over value, it can be accessed from the closure object.&lt;/p&gt;&lt;a href="#mutations"&gt;
&lt;h3 id="mutations"&gt;Mutations&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Another major oversight is the assumption that objects can only point from the stack into the heap.  If Scheme was a purely functional language, this would be entirely accurate: new objects can refer to old objects, but there is no way that a preexisting object can be made to refer to a newly created object.  For that, you need to support mutation.&lt;/p&gt;
&lt;p&gt;But Scheme does support mutation! So what happens when you use &lt;tt&gt;vector-set!&lt;/tt&gt;  to store a newly created, stack-allocated value in an old, heap-allocated vector?  If we used the above algorithm, the newly created element would either be part of the live set and get copied, but the vector's pointer would not be updated, or it wouldn't be part of the live set and the object would be lost in the stack reset.&lt;/p&gt;
&lt;p&gt;The answer to this problem is also pretty simple: we add a so-called &lt;i&gt;write barrier&lt;/i&gt;.  Whenever a value is written to an object, it is remembered.  Then, when performing a GC, these remembered values are considered to be part of the live set, just like the addresses in the saved call.  This is also the reason CHICKEN always shows the number of mutations when you're asking for GC statistics: mutation may slow down a program because GCs might take longer.&lt;/p&gt;&lt;a href="#stack-size"&gt;
&lt;h3 id="stack-size"&gt;Stack size&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;How does CHICKEN know when the stack is filled up?  It turns out that there is no portable way to detect how big the stack is, or whether it has a limit at all!&lt;/p&gt;
&lt;p&gt;CHICKEN works around this simply by limiting its stack to a predetermined size.  On 64-bit systems, this is 1MB, on 32-bit systems it's 256KB.  There is also no portable way of obtaining the address of the stack itself.  On some systems, it uses a small bit of assembly code to check the stack pointer.  On other systems, it falls back on &lt;tt&gt;alloca()&lt;/tt&gt;, allocating a trivial amount of data.  The address of the allocated data is the current value of the stack pointer.&lt;/p&gt;
&lt;p&gt;When initialising the runtime, just before the entry point is called, the stack's address is taken to determine the stack's bottom address. The top address is checked in the continuation functions, and the difference between the two is the current stack size.&lt;/p&gt;&lt;a href="#a-small-rant"&gt;
&lt;h2 id="a-small-rant"&gt;A small rant&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;While doing the background research for this post, I wanted to read Cheney's original paper.  It was very frustrating to find so many references to it, which all lead to a &lt;a href="http://dl.acm.org/citation.cfm?id=362798&amp;amp;coll=ACM&amp;amp;dl=ACM" class="external"&gt;a paywall on the ACM website&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I think it's absurd that the ACM charges $15 for a paper which is over forty years old, and only two measly pages long.  What sane person would plunk down 15 bucks to read 2 pages, especially if it is possibly outdated, or not even the information they're looking for?&lt;/p&gt;
&lt;p&gt;The ACM's motto is &amp;quot;Advancing Computing as a Science &amp;amp; Profession&amp;quot;, but I don't see how putting essential papers behind a paywall is advancing the profession, especially considering how many innovations now happen as unpaid efforts in the open source/free software corner of the world.  Putting such papers behind a paywall robs the industry from a sorely-needed historical perspective, and it stifles innovation by forcing us to keep reinventing the wheel.&lt;/p&gt;
&lt;p&gt;Some might argue that the ACM needs to charge money to be able to host high-quality papers and maintain its high quality standard, but I don't buy it.  You only need to look at &lt;a href="https://www.usenix.org/" class="external"&gt;USENIX&lt;/a&gt;, which is a similar association. They provide complete and perpetual access to all conference proceedings, and the authors maintain full rights to their work.  The ACM, instead, has now come up with a new &lt;a href="http://authors.acm.org/main.html" class="external"&gt;&amp;quot;protection&amp;quot; racket&lt;/a&gt;, requiring authors to give full control of their rights to the ACM, or pay for the privilege of keeping the rights &lt;i&gt;on their own work&lt;/i&gt;, which is between $1,100 and $1,700 per article.&lt;/p&gt;
&lt;p&gt;On a more positive note, authors are given permission to post drafts of their papers on their own website or through their &amp;quot;&lt;a href="http://www.acm.org/publications/acm-author-izer-service" class="external"&gt;Author-izer&lt;/a&gt;&amp;quot; service.  Unfortunately, this service &lt;b&gt;only&lt;/b&gt; works when the link is followed directly from the domain on which the author's website is located (through the &lt;tt&gt;Referer&lt;/tt&gt; header).  This is not how the web works: it breaks links posted in e-mail as well as search engines.&lt;/p&gt;
&lt;p&gt;Secondly, the ACM are also &lt;a href="http://www.acm.org/news/featured/author-rights-management" class="external"&gt;allowing&lt;/a&gt; their special interest groups to provide full access to conference papers of the most recent conference.  However, this doesn't seem to be encouraged in any way, and only a few SIGs seem to do this.&lt;/p&gt;
&lt;p&gt;Luckily, I found &lt;a href="http://people.cs.umass.edu/~emery/classes/cmpsci691s-fall2004/papers/p677-cheney.pdf" class="external"&gt;a copy of the Cheney paper&lt;/a&gt; on some course website.  So do yourself a favour and get it before it's taken down :(&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update&lt;/b&gt;: If you are also concerned about this, please take a small moment to add your name to &lt;a href="https://teardownthispaywall.appspot.com/" class="external"&gt;this petition&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update 2&lt;/b&gt;: I've become aware of a web site called &lt;a href="https://en.wikipedia.org/wiki/Sci-hub" class="external"&gt;Sci-Hub&lt;/a&gt; that makes papers freely available to all.  It bypasses paywalls through shared full-access accounts.  Sadly, this is technically still illegal in many countries and some of its domains have been seized in attempts at censoring them.&lt;/p&gt;&lt;a href="#further-reading"&gt;
&lt;h2 id="further-reading"&gt;Further reading&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Garbage collection is a fascinating subject whose roots can be traced back all the way to the origins of LISP.  There's plenty of information to be found:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.memorymanagement.org/" class="external"&gt;http://www.memorymanagement.org/&lt;/a&gt; is a great one-stop reference.&lt;/li&gt;
&lt;li&gt;Felix Winkelmann, CHICKEN's original author, has &lt;a href="https://media.ccc.de/browse/conferences/froscon/2013/c116_lisp_-_2013-08-24_16:30_-_scheme_implementation_techniques_-_felix_-_1258.html" class="external"&gt;presented&lt;/a&gt; about Scheme implementation techniques at FrOSCon, which included a bit about CPS conversion and garbage collection.  The &lt;a href="http://www.call-with-current-continuation.org/scheme-implementation-techniques.pdf" class="external"&gt;slides&lt;/a&gt; are also available for download.&lt;/li&gt;
&lt;li&gt;The original &amp;quot;&lt;a href="https://en.wikisource.org/wiki/Lambda_Papers" class="external"&gt;Lambda papers&lt;/a&gt;&amp;quot; are a must-read if you want to study the beginnings of Scheme.&lt;/li&gt;
&lt;li&gt;Speaking about historical information: Matthias Felleisen teaches a course on the History of Programming Languages, which includes &lt;a href="http://www.ccs.neu.edu/home/matthias/369-s04/Transcripts/gc.html" class="external"&gt;some notes on the history of garbage collection&lt;/a&gt;, and about &lt;a href="http://www.ccs.neu.edu/home/matthias/369-s04/Transcripts/PeterD-GC-WriteUp.html" class="external"&gt;concurrent garbage collection&lt;/a&gt; as well.&lt;/li&gt;
&lt;li&gt;I found a few surveys of garbage collection techniques: By &lt;a href="http://3e8.org/pub/pdf-t1/gcsurvey.pdf" class="external"&gt;Wilson&lt;/a&gt;, by &lt;a href="http://www.chasewoerner.org/chapter2.pdf" class="external"&gt;Chase&lt;/a&gt; and by &lt;a href="http://pages.cs.wisc.edu/~zhong/termproj_surveyGC.html" class="external"&gt;Zhong&lt;/a&gt;. The Zhong paper has missing images, unfortunately.  The original (with images!) can be found as a &lt;a href="http://www-2.dc.uba.ar/materias/plp/20052C/download/GCSurvey.zip" class="external"&gt;zipped MS Word document&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;</content>
    <id>tag:more-magic,2014-03-29:/posts/internals-gc.html</id>
    <published>2014-03-29T10:58:20Z</published>
    <title type="text">CHICKEN internals: the garbage collector</title>
    <updated>2014-03-29T10:58:20Z</updated>
    <link href="https://www.more-magic.net/posts/internals-gc.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;Today I'd like to talk about how CHICKEN Scheme handles distribution of language extensions (which we call &amp;quot;eggs&amp;quot;).  There are some unique features of our setup that might be interesting to users of other languages as well, and I think the way backwards compatibility was kept is rather interesting.&lt;/p&gt;&lt;a href="#in-the-beginning"&gt;
&lt;h2 id="in-the-beginning"&gt;In the beginning&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;First, a little bit of history, so you know where we're coming from. CHICKEN was initially released in the year 2000, and the core system was available as a tarball on the website.  In 2002 it was moved into CVS and in 2004 to &lt;a href="http://lists.nongnu.org/archive/html/chicken-users/2004-11/msg00066.html" class="external"&gt;Darcs&lt;/a&gt; (yes, there were &lt;i&gt;good&lt;/i&gt; open source DVCSes before Git).&lt;/p&gt;
&lt;p&gt;Throughout this period, eggs were simply stored as tarballs (curiously bearing a &amp;quot;&lt;tt&gt;.egg&lt;/tt&gt;&amp;quot; extension) in some well-known directory on the CHICKEN website.  The egg installation tool had this location built in.  For example, the egg named &lt;tt&gt;foo&lt;/tt&gt; would be fetched from &lt;tt&gt;http://www.call-with-current-continuation.org/eggs/foo.egg&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;To contribute (or update!) an extension, you simply sent a tarball to Felix and he would upload it to the site.  This was a very centralised way of working, creating a lot of work for Felix.  So in 2005, he &lt;a href="http://lists.nongnu.org/archive/html/chicken-users/2005-10/msg00115.html" class="external"&gt;asked&lt;/a&gt; authors to put all eggs in a version control system: Subversion.  At the time, every contributer was &lt;a href="http://lists.nongnu.org/archive/html/chicken-users/2005-11/msg00017.html" class="external"&gt;given write access&lt;/a&gt; to the entire repo!  These were simpler times, when we had only a handful of contributors.&lt;/p&gt;
&lt;p&gt;The switch to Subversion allowed for a neat trick: whenever an egg was modified, it triggered a &lt;a href="https://bugs.call-cc.org/browser/egg-post-commit.scm?rev=4" class="external"&gt;&amp;quot;post-commit hook&amp;quot;&lt;/a&gt; which tarred up the egg and uploaded it to the website.  This was a very simple addition which automated the work done by Felix, while ensuring the existing tools did not have to be modified.  Egg authors now had the freedom to modify their code as they liked, and new releases would appear for download within seconds.&lt;/p&gt;
&lt;p&gt;If an author used the conventional trunk/tags/branches layout, the post-commit hook automatically detected this and would upload the latest tag.  In other words, we reached a level of automation where &amp;quot;making a release&amp;quot; was simply tagging your code!&lt;/p&gt;
&lt;p&gt;Documentation for eggs originally lived on the same website as the eggs did, but this was eventually moved into &lt;a href="http://lists.nongnu.org/archive/html/chicken-users/2006-05/msg00195.html" class="external"&gt;svnwiki&lt;/a&gt;, one of the first wikis to use Subversion as a backing store.  To make things even simpler, the core system was also &lt;a href="http://lists.nongnu.org/archive/html/chicken-users/2006-06/msg00113.html" class="external"&gt;moved into Subversion&lt;/a&gt;.  Now everything was in one system, for everyone to hack on, using the same credentials everywhere.  Life was good!&lt;/p&gt;&lt;a href="#start-of-the-dvcs-wars"&gt;
&lt;h2 id="start-of-the-dvcs-wars"&gt;Start of the DVCS wars&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;This worked great for years, and the number of contributors steadily increased.  Meanwhile, distributed version control systems were gaining mainstream popularity, and contributors started experimenting with Git, Mercurial, Bazaar and Fossil.  People &lt;a href="http://lists.nongnu.org/archive/html/chicken-users/2007-08/msg00055.html" class="external"&gt;grumbled&lt;/a&gt; that CHICKEN was still on Subversion.&lt;/p&gt;
&lt;p&gt;The next major release, CHICKEN 4.0, provided for a &amp;quot;clean slate&amp;quot;, with the opportunity to &lt;a href="http://lists.nongnu.org/archive/html/chicken-users/2008-08/msg00172.html" class="external"&gt;rewrite the distribution system&lt;/a&gt;.  This simplified things, replacing the brittle post-commit script with a CGI program called &amp;quot;henrietta&amp;quot;, which would serve the eggs via HTTP.  The download location for eggs was put into a configuration file, which allowed users to host their own mirror.  This is useful if for example a company wants to set up a private deployment-server containing proprietary eggs.  We also gained a mirror for general use, graciously provided by &lt;a href="http://www.snell-pym.org.uk/alaric" class="external"&gt;Alaric&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The difference was that now there was no static tarball, but when you downloaded an egg, its files would be served straight from either svn, a local directory tree or a website.  If we ever decided to migrate the egg repository to a completely different version control system, we could simply add a new back-end to Henrietta.  Nothing would have to be modified on the client.&lt;/p&gt;&lt;a href="#the-new-system"&gt;
&lt;h2 id="the-new-system"&gt;The new system&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;In 2009, CHICKEN core was &lt;a href="http://lists.nongnu.org/archive/html/chicken-users/2009-10/msg00086.html" class="external"&gt;moved into a Git repository&lt;/a&gt;, as it looked like Git was winning the DVCS wars.  New users were often complaining about having to use crusty old Subversion.  By this time, people even &lt;a href="http://lists.nongnu.org/archive/html/chicken-users/2010-08/msg00072.html" class="external"&gt;used DVCSes exclusively&lt;/a&gt;, only synchronising to the svn repo.  This meant it was no longer the &amp;quot;canonical&amp;quot; repository for all eggs.  It was becoming nothing but a hassle for those who preferred other VCSes.&lt;/p&gt;
&lt;p&gt;Another problem was that we had still a maintenance problem: commit access on the svn repo is centrally managed, through one big &lt;a href="http://svnbook.red-bean.com/en/1.7/svn.serverconfig.httpd.html#svn.serverconfig.httpd.authz.perdir" class="external"&gt;mod_authz_svn&lt;/a&gt; configuration file, listing which users have access to which &amp;quot;sub-repositories&amp;quot;.  If someone wants to grant commit access to another developer, this has to be requested via the mailing list or the server's maintainer.&lt;/p&gt;&lt;a href="#requirements"&gt;
&lt;h3 id="requirements"&gt;Requirements&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;To solve these problems, we started to &lt;a href="http://lists.nongnu.org/archive/html/chicken-hackers/2011-03/msg00000.html" class="external"&gt;consider&lt;/a&gt; new ways to allow users to develop their eggs using their favorite VCS.  The new system had a few strict requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It had to be completely backwards-compatible.  No changes should be made to CHICKEN core.  New eggs published through this system should be available to older CHICKENs, too.&lt;/li&gt;
&lt;li&gt;It had to be completely VCS-independent.  We want to avoid extra work when the next VCS fad comes along.  Furthermore, it should work with all popular code hosters, for maximum freedom of choice. Self-hosting should explicitly be an option.&lt;/li&gt;
&lt;li&gt;The existing workflow of egg authors should not fundamentally change; especially the release procedure of making a tag should stay.&lt;/li&gt;
&lt;li&gt;There should be a way to avoid broken links if someone takes down their repo.&lt;/li&gt;
&lt;li&gt;Most of all, the system had to be &lt;i&gt;simple&lt;/i&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;a href="#a-simple-solution"&gt;
&lt;h3 id="a-simple-solution"&gt;A simple solution&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;The simplest way to make the distribution system VCS-independent is to ignore VCSes altogether!  Instead, we download source files over HTTP and mirror them from the CHICKEN server.&lt;/p&gt;
&lt;p&gt;This idea was rather natural: our Subversion setup had always allowed direct access to plain files over HTTP through &lt;tt&gt;mod_dav_svn&lt;/tt&gt;.  Most popular code hosting sites (Github, Bitbucket, Google Code etc) also allow this, either directly or via some web repo viewer's &amp;quot;download raw file&amp;quot; link, which can be constructed from a VCS tag and file name. Also, Henrietta already supported serving eggs from a local directory tree which meant we had to make almost no modifications to our existing tool chain.&lt;/p&gt;
&lt;p&gt;To make this work, all that's needed is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Some daemon which periodically fetches new eggs.&lt;/li&gt;
&lt;li&gt;A &amp;quot;master list&amp;quot; of where each egg is hosted.&lt;/li&gt;
&lt;li&gt;For each egg, a list of released versions for that egg.&lt;/li&gt;
&lt;li&gt;A &amp;quot;base URI&amp;quot; where the files for that release can be downloaded.&lt;/li&gt;
&lt;li&gt;A list of files for that release (or the name of a tarball, which is equivalent).&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;We already had a so-called &amp;quot;&lt;tt&gt;.meta&lt;/tt&gt;-file&amp;quot;, which contains info about the egg (author, license, name, category etc).  In an earlier incarnation of the post-commit hook this file also contained a list of the files that the egg consisted of, so it made sense to re-use this facility.&lt;/p&gt;
&lt;p&gt;We only needed to take care of the daemon, the master egg list and a way to communicate the base URI.  This was simple, and I wrote the daemon (dubbed &amp;quot;&lt;a href="http://wiki.call-cc.org/eggref/4/henrietta-cache" class="external"&gt;henrietta-cache&lt;/a&gt;&amp;quot;) over a weekend during a hackathon.  It really is simple and consists of only 300+ lines of (rather ugly) Scheme code.  At the hackathon, &lt;a href="http://ceaude.twoticketsplease.de/" class="external"&gt;Moritz&lt;/a&gt; helped out by moving the existing eggs to this new scheme, and testing with various hosting providers.&lt;/p&gt;&lt;a href="#but-not-the-simplestsolution"&gt;
&lt;h4 id="but-not-the-simplestsolution"&gt;But not the &lt;i&gt;simplest&lt;/i&gt; solution&lt;/h4&gt;&lt;/a&gt;
&lt;p&gt;The clever reader has probably already noted that the setup could be simplified by putting the henrietta-cache logic into the client program.  We chose not to do this because it would break two requirements: that of backwards compatibility and that of avoiding broken links.&lt;/p&gt;
&lt;p&gt;Strictly speaking, the backwards compatibility problem could be solved by embedding the functionality into &lt;tt&gt;chicken-install&lt;/tt&gt; and eventually removing henrietta-cache from the server.&lt;/p&gt;
&lt;p&gt;Broken links are a bigger problem, though.  Currently, if a repo becomes unavailable, this is no problem; we still have a cached copy on our servers.  Even if the repo goes offline forever and nobody has a copy of it anymore, we can still import the cached files into a fresh repo and take over maintenance from there.&lt;/p&gt;&lt;a href="#some-incremental-improvements"&gt;
&lt;h3 id="some-incremental-improvements"&gt;Some incremental improvements&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Unfortunately, the new system made it &lt;i&gt;easier&lt;/i&gt; for Github and Bitbucket users than for CHICKEN Subversion users to maintain their eggs, because these sites allow tarball downloads, while the Subversion users had to list each file in their egg in the meta file. Under the old system this was not required, because it simply offered the entire svn egg directory for download.&lt;/p&gt;
&lt;p&gt;After some people complained about having to do this extra step, I wrote another simple &amp;quot;helper&amp;quot; egg with the tongue-in-cheek name &lt;a href="http://wiki.call-cc.org/eggref/4/pseudo-meta-egg-info" class="external"&gt;&amp;quot;pseudo-meta-egg-info&amp;quot;&lt;/a&gt;. This is a small (80 lines) Spiffy web application which can generate &amp;quot;pseudo&amp;quot; meta files containing a full list of all the files in a Subversion subdirectory, and a list of all the tags available.  This all happens on-the-fly, which means that egg authors could now revert to their old workflow of simply tagging their egg to make a release!&lt;/p&gt;
&lt;p&gt;Technically, this helper webapp can be extended and deployed for any hosting site, so if you decide to host your own repository it could generate the list of tags and files for that, too.  CHICKEN isn't big enough to ask Google, Github or Bitbucket to run this on their servers, of course, so some helper plug-ins and shell scripts for &lt;a href="http://wiki.call-cc.org/eggref/4/svn-egg-author" class="external"&gt;svn&lt;/a&gt;, &lt;a href="https://bitbucket.org/sjamaan/egg-author" class="external"&gt;hg&lt;/a&gt; and &lt;a href="https://wiki.call-cc.org/eggref/4/git-egg-author" class="external"&gt;git&lt;/a&gt; were made as well.  These will generate the list of tags and file names and put them in the meta- and release-info files.&lt;/p&gt;&lt;a href="#current-status"&gt;
&lt;h2 id="current-status"&gt;Current status&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;The new system has been in use for over two years (since March 29th, 2011) and it has been doing a good job, requiring only very little maintenance and few modifications after the initial release.  We've already reaped the benefits of our setup: Github and Bitbucket both had several periods of downtime, during which eggs were still available, even if they were hosted there.&lt;/p&gt;
&lt;p&gt;The following graph shows the number of available CHICKEN eggs, starting with the &amp;quot;release 4&amp;quot; branch (requires an SVG-capable browser).  There's a small skew because the script I used to generate the graph only checked for existence, not whether the egg was released.&lt;/p&gt;
&lt;p&gt;&lt;img src="/pics/distributed-repo-usage-2013-06.svg" /&gt;&lt;/p&gt;
&lt;p&gt;As you can see, Mercurial (hg) and Git took off almost simultaneously, but where git is still steadily increasing in popularity, hg mostly stagnated.  Subversion (svn) saw a few drops from eggs that were moved into hg/git.  You'd guess that most git users would use Github, but it turns out that Bitbucket is reasonably popular among Chicken users too.  We also have three authors who have opted to host their own repositories.  You can see this in the breakdown of today's eggs by host:&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;Hosting site&lt;/th&gt;
&lt;th&gt;VCSes&lt;/th&gt;
&lt;th&gt;# of eggs&lt;/th&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;code.call-cc.org&lt;/td&gt;
&lt;td&gt;svn&lt;/td&gt;
&lt;td align="right"&gt;454&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;github.com&lt;/td&gt;
&lt;td&gt;git&lt;/td&gt;
&lt;td align="right"&gt;85&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;bitbucket.org&lt;/td&gt;
&lt;td&gt;hg, git&lt;/td&gt;
&lt;td align="right"&gt;41&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;gitorious.org&lt;/td&gt;
&lt;td&gt;git&lt;/td&gt;
&lt;td align="right"&gt;5&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;chust.org&lt;/td&gt;
&lt;td&gt;fossil&lt;/td&gt;
&lt;td align="right"&gt;5&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;kitten-technologies.co.uk&lt;/td&gt;
&lt;td&gt;fossil&lt;/td&gt;
&lt;td align="right"&gt;3&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;code.stapelberg.de&lt;/td&gt;
&lt;td&gt;git&lt;/td&gt;
&lt;td align="right"&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Finally, the graph shows that people are still releasing new eggs from svn, but most new development takes place in git.  And yes, there are a few eggs in Fossil, too!  Bazaar is currently not listed.  One possible explanation is that Loggerhead (its web viewer) does not allow easy construction of stable URLs to raw files for a particular tag (or zip file/tarball), so serving up eggs straight from a repo is not possible.  Another reason could be that bzr simply isn't that popular among CHICKEN users.  If you're a bzr user and would like to use this distribution scheme, please have a look at Loggerhead issues &lt;a href="https://bugs.launchpad.net/loggerhead/+bug/473691" class="external"&gt;#473691&lt;/a&gt; and &lt;a href="https://bugs.launchpad.net/loggerhead/+bug/739022" class="external"&gt;#739022&lt;/a&gt;.  If you know a way around this, please share your knowledge on our &lt;a href="http://wiki.call-cc.org/releasing-your-egg#launchpad-bazaar" class="external"&gt;release instructions page&lt;/a&gt;.&lt;/p&gt;&lt;a href="#things-to-improve"&gt;
&lt;h3 id="things-to-improve"&gt;Things to improve&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;Needless to say, I'm rather happy that the system satisfied all the requirements we set for it, and that it saw such uptake.  The majority of newly released eggs are using one of the new systems (too bad it's Git, but I guess that's inevitable).&lt;/p&gt;
&lt;p&gt;However, as always, there is room for improvement.  The current system has a few flaws, all of which are due to the fact that henrietta-cache simply copies code off an external site:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There's no &amp;quot;stable&amp;quot; tarball per egg release.  This is required for OS package managers, which usually verify with a checksum whether the source package has not changed.  Recently, &lt;a href="http://parenteses.org/mario/" class="external"&gt;Mario&lt;/a&gt; improved on this situation by providing &lt;a href="http://code.call-cc.org/egg-tarballs/" class="external"&gt;tarballs&lt;/a&gt;, but these are merely tarballs of the henrietta-cache mirror on that particular server.  However, these &lt;i&gt;should&lt;/i&gt; be expected to be stable...&lt;/li&gt;
&lt;li&gt;If an egg author moves tags around, nobody will know.  Different henrietta-cache mirrors may then have an inconsistent view of the distributed repository.  We have two egg mirrors, and so far this has happened once or twice.  This requires some manual intervention: just blow away all the cached files and wait for it to re-synch, or trigger the synch manually.&lt;/li&gt;
&lt;li&gt;Egg authors cannot sign their eggs; each egg is downloaded from a source that may not be trustworthy.  This is tricky, especially because most people don't want to mess around with PGP keys anyway. CHICKEN core releases aren't signed either, so this isn't very high on our priority list.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;I think some of these problems are a result of &amp;quot;going distributed&amp;quot;, similar to the problem that you should not rewrite history that has already been pushed.&lt;/p&gt;</content>
    <id>tag:more-magic,2013-06-04:/posts/vcs-independent-distribution.html</id>
    <published>2013-06-04T21:30:09Z</published>
    <title type="text">VCS-independent distribution of language extensions</title>
    <updated>2013-06-04T21:30:09Z</updated>
    <link href="https://www.more-magic.net/posts/vcs-independent-distribution.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;Recently there was a &lt;a href="http://lists.nongnu.org/archive/html/chicken-hackers/2013-02/msg00054.html" class="external"&gt;small flame war&lt;/a&gt; on the Chicken-hackers mailing list.  A user new to Scheme asked an innocuous question that drew some heated responses:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; Is there a good reason for this behavior?
 # perl -e 'print substr(&amp;quot;ciao&amp;quot;,0,10);'
 ciao 
 # ruby -e 'puts &amp;quot;ciao&amp;quot;[0..10]'
 ciao
 # python -c 'print &amp;quot;ciao&amp;quot;[0:10];'
 ciao
 # csi -e '(print (substring &amp;quot;ciao&amp;quot; 0 10))'
 Error: (substring) out of range 0 10&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Some popular dynamic languages have a generic &amp;quot;slice&amp;quot; operator which allows the user to supply an end index that's beyond the end of the object, and it'll return from the start position up until the end. Instead, Chicken (and most other Schemes) will raise an error.&lt;/p&gt;
&lt;p&gt;On the list, I argued that taking characters 0 through 10 from a 3-character string &lt;i&gt;makes no bloody sense&lt;/i&gt;, which is why it's signalling an error.  For the record: this can be caught by an exception handler, which makes it a controlled error situation, not a &amp;quot;crash&amp;quot;.&lt;/p&gt;
&lt;p&gt;Our new user retorted that it's perfectly sane to &lt;i&gt;define&lt;/i&gt; the &lt;tt&gt;substring&lt;/tt&gt; procedure as:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; Return a string consisting of the characters between the start position
 and the end position, or the end of the string, whichever comes first.&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;I think this is a needlessly complex definition.  It breaks the rule &lt;a href="http://www.catb.org/esr/writings/taoup/html/ch01s06.html#id2873301" class="external"&gt;&amp;quot;do one thing and do it well&amp;quot;&lt;/a&gt;, from which UNIX derives its power: Conceptually crisp components ease composition.&lt;/p&gt;
&lt;p&gt;One of the most valuable things a programming language can offer is &lt;i&gt;the ability to reason about code with a minimum of extra information&lt;/i&gt;.  This is also why most Schemers prefer a functional programming style; it's easier to reason about &lt;a href="https://en.wikipedia.org/wiki/Referential_transparency_%28computer_science%29" class="external"&gt;referentially transparent&lt;/a&gt; code.  Let's see what useful facts we can infer from a single &lt;tt&gt;(substring s 0 10)&lt;/tt&gt; call:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The variable &lt;tt&gt;s&lt;/tt&gt; is a string.&lt;/li&gt;
&lt;li&gt;The string &lt;tt&gt;s&lt;/tt&gt; is at least 10 characters long.&lt;/li&gt;
&lt;li&gt;The returned value is a string.&lt;/li&gt;
&lt;li&gt;The returned string is exactly 10 characters long.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;If either of the preconditions doesn't hold, it's an error situation and the code following the substring call will not be executed.  The above guarantees also mean, for example, that if later you see &lt;tt&gt;(string-ref s 8)&lt;/tt&gt; this will &lt;i&gt;always&lt;/i&gt; return a character.  In &amp;quot;sloppier&amp;quot; languages, you lose several of these important footholds. This means you can't reason so well about your code's correctness anymore, except by reading back and dragging in more context.&lt;/p&gt;
&lt;p&gt;Finally, it is also harder to build the &amp;quot;simple&amp;quot; version of substring on top of the complex one than it is to build the complex one as a &amp;quot;convenience&amp;quot; layer on top of the simpler one.  On our list it was &lt;a href="http://lists.nongnu.org/archive/html/chicken-hackers/2013-02/msg00060.html" class="external"&gt;quickly shown&lt;/a&gt; that it's trivial to do so:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;substring/n s start n&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let*&lt;/span&gt;&lt;/i&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;start &lt;span class="paren5"&gt;(&lt;span class="default"&gt;min start &lt;span class="paren6"&gt;(&lt;span class="default"&gt;string-length s&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren4"&gt;(&lt;span class="default"&gt;end &lt;span class="paren5"&gt;(&lt;span class="default"&gt;min &lt;span class="paren6"&gt;(&lt;span class="default"&gt;string-length s&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren6"&gt;(&lt;span class="default"&gt;+ start n&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;substring s start end&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="comment"&gt;;; Easy to use and re-use:
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;substring/n &lt;span class="string"&gt;&amp;quot;ciao&amp;quot;&lt;/span&gt; 1 10&lt;/span&gt;)&lt;/span&gt; =&amp;gt; &lt;span class="string"&gt;&amp;quot;iao&amp;quot;&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;There's even an egg for Chicken called &lt;a href="http://wiki.call-cc.org/eggref/4/slice" class="external"&gt;slice&lt;/a&gt; which provides a generic procedure which behaves like the ranged index operator in Python/Ruby.&lt;/p&gt;&lt;a href="#a-tangential-rant-on-the-hidden-costs-of-sloppiness"&gt;
&lt;h2 id="a-tangential-rant-on-the-hidden-costs-of-sloppiness"&gt;A tangential rant on the hidden costs of sloppiness&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;The difference in behaviour between these languages is not a coincidence: it's a result of deep cultural differences.  The Scheme culture (and in some respects the broader Lisp culture) is one that tends to prefer correctness and precision.  This appears in many forms, from Shivers' &lt;a href="http://www.scsh.net/docu/post/sre.html" class="external"&gt;&amp;quot;100% correct solution&amp;quot; manifesto&lt;/a&gt; to Gabriel's &lt;a href="http://dreamsongs.com/WIB.html" class="external"&gt;Worse Is Better&lt;/a&gt; essay and all the &lt;a href="http://library.readscheme.org/page3.html" class="external"&gt;verbiage&lt;/a&gt; dedicated to correct &amp;quot;hygienic&amp;quot; treatment of macros.&lt;/p&gt;
&lt;p&gt;In contrast, some cultures prefer lax and &amp;quot;do what I mean&amp;quot; over rigid and predictable behaviour.  This may be more convenient for writing quick one-off scripts, but in my opinion this is just asking for trouble when writing serious programs.&lt;/p&gt;
&lt;p&gt;Let's investigate some examples of the consequences of this &amp;quot;lax&amp;quot; attitude.  You're probably aware of the recent discovery of several vulnerabilities in Ruby on Rails.  Two of these allowed remote code execution simply by submitting a &lt;tt&gt;POST&lt;/tt&gt; request to &lt;i&gt;any&lt;/i&gt; Rails application.  As &lt;a href="http://www.insinuator.net/2013/01/rails-yaml/" class="external"&gt;this post&lt;/a&gt; explains, the parser for XML requests was &amp;quot;enhanced&amp;quot; to automatically parse embedded YAML documents (which can contain arbitrary code).  My position is that YAML has absolutely &lt;i&gt;nothing&lt;/i&gt; to do with XML (or &lt;a href="http://ronin-ruby.github.com/blog/2013/01/28/new-rails-poc.html" class="external"&gt;JSON&lt;/a&gt;), which means that if a program wants to parse YAML embedded in XML it must do that itself, or at least explicitly specify it wants automatic type conversions in XML/JSON documents.  The Rails developers allowed misplaced convenience and sloppiness to trump precision and correctness, to the point that nobody knew what their code &lt;i&gt;really&lt;/i&gt; did.&lt;/p&gt;
&lt;p&gt;Another example would be the way PHP, Javascript, and several other languages implicitly coerce types.  You can see the hilarious results of the confusion this can cause in the brilliant talk titled &lt;a href="https://www.destroyallsoftware.com/talks/wat" class="external"&gt;&amp;quot;Wat&amp;quot;&lt;/a&gt;.  There are also people filing &lt;a href="https://bugs.php.net/bug.php?id=54547" class="external"&gt;bug reports&lt;/a&gt; for PHP's &lt;tt&gt;==&lt;/tt&gt; operator.  Its implicit type conversion is documented, intended, behaviour but it results in a lot of confusion and, again, security issues, as pointed out by &lt;a href="http://www.phpsadness.com/sad/47" class="external"&gt;PHP Sadness #47&lt;/a&gt;.  If you allow the programmer to be sloppy and leave important details unspecified, an attacker will gladly fill in those details for you.&lt;/p&gt;
&lt;p&gt;Some more fun can be had by looking at the MySQL database and how it mangles data.  The PostgreSQL culture also strongly prefers correctness and precision, whereas MySQL's culture is more lax.  The clash between these two cultures can be seen in &lt;a href="http://www.postgresql.org/message-id/20121129142726.69290@gmx.com" class="external"&gt;a thread on the PostgreSQL mailinglist&lt;/a&gt; where someone posted a video of a comparison between PostgreSQL and MySQL's behaviour.  These cultural differences run deep, as you can tell by the responses of shock.  And again, the lax behaviour of MySQL has security implications.  The Rails folks have discovered that &lt;a href="http://www.openwall.com/lists/oss-security/2013/02/06/7" class="external"&gt;common practices might allow attackers to abuse MySQL's type coercion&lt;/a&gt;. Because Rails supports passing typed data in queries, it's possible to force an integer in a condition that expects a string.  MySQL will silently coerce non-numerical strings to zero:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight sql-language"&gt;SELECT * FROM `users` WHERE `login_token` = 0 LIMIT 1;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This will match the first record (which usually just &lt;i&gt;happens&lt;/i&gt; to be the administrative account).  Just as with the innocent little substring behaviour we started our journey with, it is possible to work around this, but things would be a lot easier if the software behaved more rigidly and strict, so that this kind of conversion would only be done upon explicit request of the programmer.&lt;/p&gt;
&lt;p&gt;Incidentally, it is possible to put MySQL into a stricter &lt;a href="http://dev.mysql.com/doc/refman/5.6/en/server-sql-mode.html" class="external"&gt;&amp;quot;SQL mode&amp;quot;&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight sql-language"&gt;SET sql_mode=&amp;#x27;TRADITIONAL&amp;#x27;;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This is rarely done, probably because most software somehow implicitly relies on this broken behaviour.  By the way, does anyone else think it's funny that this mode is called &amp;quot;traditional&amp;quot;?  As if it were somehow old-fashioned to expect precise and correct behaviour!&lt;/p&gt;&lt;a href="#take-back-control"&gt;
&lt;h2 id="take-back-control"&gt;Take back control&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;It is high time people realised that implicit behaviour and unclear specifications are a recipe for disaster.  Computers are by nature rigid and exact.  This is a &lt;i&gt;feature&lt;/i&gt; we should embrace.  Processes in the &amp;quot;real world&amp;quot; are often fuzzy and poorly defined, usually because they are poorly understood.  As programmers, it's our &lt;i&gt;job&lt;/i&gt; to keep digging until we have enough information to describe the task to a computer.  Making APIs fuzzier is the wrong response to this problem, and a sign of weakness.  Do you prefer to know &lt;i&gt;exactly&lt;/i&gt; what your program will do, or would you rather admit defeat and allow fuzziness to creep into your programs?&lt;/p&gt;
&lt;p&gt;In case you're wondering, this rant didn't come out of the blue.  One of three reasons this blog is called &lt;i&gt;more magic&lt;/i&gt; is as a wry reference to the trend of putting more &amp;quot;magic&amp;quot; into APIs, which makes them hard to control.  This is a recurring frustration of mine and I would like to see a move towards &lt;i&gt;less magic&lt;/i&gt; of this kind.  Yeah, I'm a cynical bastard ;)&lt;/p&gt;</content>
    <id>tag:more-magic,2013-02-17:/posts/thoughts-on-substring.html</id>
    <published>2013-02-17T10:57:03Z</published>
    <title type="text">Random thoughts on the substring procedure</title>
    <updated>2013-02-17T10:57:03Z</updated>
    <link href="https://www.more-magic.net/posts/thoughts-on-substring.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;I've finally decided to get a &lt;i&gt;proper&lt;/i&gt; domain name: &lt;a href="http://www.more-magic.net" class="external"&gt;http://www.more-magic.net&lt;/a&gt;. Please update your bookmarks and feed readers!&lt;/p&gt;
&lt;p&gt;I used to run this blog on a hostname from the good folks at &lt;a href="http://www.dyndns.org" class="external"&gt;DynDNS&lt;/a&gt;, which I registered in my college days.  DynDNS had the benefit of being 100% free (great for poor college students!), but the disadvantage of having to run a tool called &lt;tt&gt;ddclient&lt;/tt&gt;.  This tool is intended to update DNS entries for hosts with dynamically assigned IP address, and if you don't run it, your hostname will expire.&lt;/p&gt;
&lt;p&gt;Occasionally &lt;tt&gt;ddclient&lt;/tt&gt; gets &amp;quot;stuck&amp;quot;, not performing updates anymore.  This happens unnoticably, until you get an e-mail from DynDNS stating that your domain will expire in 5 days unless you click the reactivation link and restart &lt;tt&gt;ddclient&lt;/tt&gt;.  The hassle of this and the risk of &lt;tt&gt;ddclient&lt;/tt&gt; getting stuck at a bad time, together with the unprofessional quality of running under a domain that's obviously not your own (and harder to remember) finally got me to consider paying for a proper domain.  So there you have it: &lt;tt&gt;more-magic.net&lt;/tt&gt; :)&lt;/p&gt;</content>
    <id>tag:more-magic,2013-02-11:/posts/new-domain.html</id>
    <published>2013-02-11T18:27:52Z</published>
    <title type="text">A new domain</title>
    <updated>2013-02-11T18:27:52Z</updated>
    <link href="https://www.more-magic.net/posts/new-domain.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;&lt;a href="/posts/structurally-fixing-injection-bugs.html" class="internal"&gt;Last time&lt;/a&gt; I explained how sloppy representations can cause various vulnerabilities.  While doing some research for that post I stumbled across NUL byte injection bugs in two projects.  Because both have been fixed now, I feel like I can freely talk about them with a &lt;a href="https://en.wikipedia.org/wiki/Responsible_disclosure" class="external"&gt;clear conscience&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;These projects are &lt;a href="http://www.call-cc.org" class="external"&gt;Chicken Scheme&lt;/a&gt; and the C implementation of &lt;a href="http://www.ruby-lang.org" class="external"&gt;Ruby&lt;/a&gt;.  The difference in the way these systems deal with NUL bytes clearly shows the importance of handling security issues in a &lt;i&gt;structural&lt;/i&gt; way.  We'll also see the importance of truly grokking the problem when implementing a fix.&lt;/p&gt;&lt;a href="#a-quick-recap"&gt;
&lt;h2 id="a-quick-recap"&gt;A quick recap&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Remember that C uses NUL bytes to delimit strings.  Many other languages store the length of the string instead.  In these languages, NUL bytes can occur inside strings.  This can cause unintended reinterpretation when strings cross the language border into C.&lt;/p&gt;
&lt;p&gt;In my previous post I already &lt;a href="/posts/structurally-fixing-injection-bugs.html#poisoned-nul-bytes" class="internal"&gt;pointed out&lt;/a&gt; how Chicken automatically prevents this reinterpretation in its foreign function interface (FFI).  You just describe to Scheme that your C function accepts a string, and it will take care of the rest:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; my-length &lt;span class="paren2"&gt;(&lt;span class="default"&gt;foreign-lambda int &lt;span class="string"&gt;&amp;quot;strlen&amp;quot;&lt;/span&gt; c-string&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

 &lt;span class="comment"&gt;;; Prints 12:
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;print &lt;span class="paren2"&gt;(&lt;span class="default"&gt;my-length &lt;span class="string"&gt;&amp;quot;hello, there&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="comment"&gt;;; Raises an exception, showing the following message:
&lt;/span&gt;&lt;span class="comment"&gt;;; Error: (##sys#make-c-string) cannot represent string with NUL
&lt;/span&gt;&lt;span class="comment"&gt;;;   bytes as C string: &amp;quot;hello\x00there&amp;quot;
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;print &lt;span class="paren2"&gt;(&lt;span class="default"&gt;my-length &lt;span class="string"&gt;&amp;quot;hello&lt;/span&gt;&lt;span class="string"&gt;\x&lt;/span&gt;&lt;span class="string"&gt;00there&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The FFI's feature of automatically checking for NUL bytes in strings before passing them on to C was only added in late 2010 (Chicken 4.6.0).  However, because &lt;i&gt;everything&lt;/i&gt; uses this interface, this mismatch could easily be fixed, in a central location, &lt;i&gt;securing all existing programs in one fell swoop&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;Now, you may be thinking &amp;quot;well, that's nothing special; it's good engineering practice that there must be a single point of truth, and that you Don't Repeat Yourself&amp;quot;.  And you'd be right!  In fact, this is a key insight: &lt;b&gt;solid engineering is a prerequisite to secure engineering&lt;/b&gt;.  It can prevent security bugs from happening, and help to fix them quickly once they are discovered.  A core tenet of &amp;quot;structural security&amp;quot; is that without structure, there can be no security.&lt;/p&gt;&lt;a href="#when-smugness-backfires"&gt;
&lt;h2 id="when-smugness-backfires"&gt;When smugness backfires&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;To drive home the point, let's take a look at what I discovered while writing my previous blog post.  After describing Chicken's Right Way solution and feeling all &lt;a href="http://c2.com/cgi/wiki?SmugLispWeenie" class="external"&gt;smug&lt;/a&gt; about it, I noticed an embarrassing problem: for various reasons (some good, others less so), there are places in Chicken where C functions are called without going through the FFI.  Some of these contained hand-rolled string conversions!&lt;/p&gt;
&lt;p&gt;It turns out that we overlooked these places when first introducing the NUL byte checks, and as a consequence several critical procedures (standard R5RS ones like &lt;tt&gt;with-input-from-file&lt;/tt&gt;) were left &lt;a href="http://lists.nongnu.org/archive/html/chicken-users/2012-09/msg00004.html" class="external"&gt;vulnerable&lt;/a&gt; to exactly this bug:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="comment"&gt;;; This program outputs &amp;quot;yes&amp;quot; twice in Chickens &amp;lt; 4.8.0
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;with-output-to-file&lt;/span&gt;&lt;/i&gt; &lt;span class="string"&gt;&amp;quot;foo&lt;/span&gt;&lt;span class="string"&gt;\x&lt;/span&gt;&lt;span class="string"&gt;00bar&amp;quot;&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;lambda&lt;/span&gt;&lt;/i&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;print &lt;span class="string"&gt;&amp;quot;hai&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;print &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;if&lt;/span&gt;&lt;/i&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;file-exists? &lt;span class="string"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;yes&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;no&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;print &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;if&lt;/span&gt;&lt;/i&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;file-exists? &lt;span class="string"&gt;&amp;quot;foo&lt;/span&gt;&lt;span class="string"&gt;\x&lt;/span&gt;&lt;span class="string"&gt;00bar&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;yes&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;no&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;To me, this just validates the importance of approaching security measures in a structural rather than an ad-hoc way; the bug was only in those parts of the code that &lt;i&gt;didn't&lt;/i&gt; use the FFI.  Deviation from a rule is where bugs are often found!&lt;/p&gt;
&lt;p&gt;You can also see that &lt;a href="http://code.call-cc.org/cgi-bin/gitweb.cgi?p=chicken-core.git;a=commitdiff;h=d9f2ad87b42ff5f545e70248a02f92c4a34e8267;hp=30b2e4ca0b20651e88d79e5d757c93d22487acc7" class="external"&gt;we fixed it&lt;/a&gt; as thoroughly as possible, especially given the at times awkward structure of the Chicken code.  We commented every special situation extensively, assigned a new error type &lt;tt&gt;C_ASCIIZ_REPRESENTATION_ERROR&lt;/tt&gt; for this particular error, and added regression tests for at least each &lt;i&gt;class&lt;/i&gt; of functionality (string to number conversion, file port creation, process creation, environment access, and low-level messaging functionality).  There's definitely room for improvement here, and I hope to one day reduce the special cases to the bare minimum.  By documenting special cases it's easy to avoid introducing new problems.  It also makes them easier to find when refactoring. The tests help there too, of course.&lt;/p&gt;
&lt;p&gt;When you run the above program in a Chicken version with the fix, it behaves like expected:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; Error: cannot represent string with NUL bytes as C string: &amp;quot;foo\x00bar&amp;quot;&lt;/tt&gt;&lt;/pre&gt;&lt;a href="#another-approach"&gt;
&lt;h2 id="another-approach"&gt;Another approach&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;The Ruby situation is a little more complicated.  It has no FFI but a C API, so it works the other way around: you write C to interface &amp;quot;up&amp;quot; into Ruby. It has a &lt;tt&gt;StringValueCStr()&lt;/tt&gt; macro, which is &lt;a href="http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/README.EXT?revision=38170&amp;amp;view=markup#l117" class="external"&gt;documented&lt;/a&gt; as follows (sic):&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; You can also use the macro named StringValueCStr(). This is just
 like StringValuePtr(), but always add nul character at the end of
 the result. If the result contains nul character, this macro causes
 the ArgumentError exception.&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;However, this isn't consistently used in Ruby's own standard library:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight ruby-language"&gt;File.open&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;foo&lt;/span&gt;&lt;span class="string"&gt;\0&lt;/span&gt;&lt;span class="string"&gt;bar&amp;quot;&lt;/span&gt;, &lt;span class="string"&gt;&amp;quot;w&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren1"&gt;{&lt;span class="default"&gt; |f| f.puts &lt;span class="string"&gt;&amp;quot;hai&amp;quot;&lt;/span&gt; &lt;/span&gt;}&lt;/span&gt;
puts File.exists?&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
puts File.exists?&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;foo&lt;/span&gt;&lt;span class="string"&gt;\0&lt;/span&gt;&lt;span class="string"&gt;bar&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;In Ruby 1.9.3p194 and earlier, this shows the following output, indicating it's &lt;a href="http://www.ruby-lang.org/en/news/2012/10/12/poisoned-NUL-byte-vulnerability/" class="external"&gt;vulnerable&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; true
 test.rb:4:in `exists?': string contains null byte (ArgumentError)
         from test.rb:4:in `&amp;lt;main&amp;gt;'&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;It turns out that internally, Ruby strings are stored with a length, but &lt;i&gt;also&lt;/i&gt; get a NUL byte tacked onto the end, to prevent copying when calling C functions.  This performance hack undermines the safety of Ruby to C string conversions, and is the direct cause of these inconsistencies.  True, there &lt;i&gt;is&lt;/i&gt; a safe function that extracts the string while checking for NUL bytes, but there are also various ways to bypass this, and if you accidentally use the wrong macro to extract the (raw) string, your code won't break.  Of course, this is only true for benign inputs...&lt;/p&gt;
&lt;p&gt;The complexity of Ruby's implementation makes it hard to ensure that it's safe everywhere.  Indeed, the various places where strings are passed to C all do it differently.  For example, the &lt;tt&gt;ENV&lt;/tt&gt; hash for manipulating the POSIX environment has its own hand-rolled test for NUL, which you can easily verify; it produces a different error message than the one &lt;tt&gt;exists?&lt;/tt&gt; gave us earlier:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;irb(main):001:0&amp;gt; ENV[&amp;quot;foo\0bar&amp;quot;] = &amp;quot;test&amp;quot;
ArgumentError: bad environment variable name&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;There is no reason this couldn't just use &lt;tt&gt;StringValueCStr()&lt;/tt&gt;.  So, even though Ruby has this safe macro, which provides a mechanism to check for poisoned NUL bytes in strings, it's rarely used by Ruby's own internals.  This could be fixed just like Chicken; here too, the best way to do that would be to generalize and eliminate all special cases.  Simpler code is easier to secure.&lt;/p&gt;&lt;a href="#a-fundamental-misunderstanding"&gt;
&lt;h2 id="a-fundamental-misunderstanding"&gt;A fundamental misunderstanding&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;When I reported the bug in the File class to the Ruby project, they quickly had a &lt;a href="http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&amp;amp;revision=37163" class="external"&gt;fix&lt;/a&gt;, but unfortunately they seemed uninterested in going through Ruby's entire code to fix &lt;i&gt;all&lt;/i&gt; string conversions (quoting from private e-mail conversation):&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; &amp;gt; I agree that this looks like a good place to fix the File/IO
 &amp;gt; class, but there are many other places where strings are passed to C.
 &amp;gt; Are all of those secured?
 All path names should be converted with &amp;quot;to_path&amp;quot; method if possible.
 If any methods don't obey the rule, it is another bug.  Please let us
 know if you find such case.&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;In retrospect, there is the possibility that I didn't quite make myself clear enough.  Perhaps this person thought I was referring to other path strings in the code.  However, to me it sounds a lot like they made the same conceptual mistake that the PHP team made when they &lt;a href="http://svn.php.net/viewvc?view=revision&amp;amp;revision=311870" class="external"&gt;&amp;quot;fixed&amp;quot; NUL injections&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The PHP solution was to add a special &lt;a href="http://svn.php.net/viewvc/php/php-src/trunk/README.PARAMETER_PARSING_API?revision=311902&amp;amp;view=markup#l54" class="external"&gt;&amp;quot;p&amp;quot; flag for converting path strings&lt;/a&gt;. This happens for all PHP functions declared in C (via &lt;tt&gt;zend_parse_parameters()&lt;/tt&gt;). By the way, notice how this is a &lt;i&gt;new&lt;/i&gt; flag.  There probably are tons of PHP extensions out there which aren't using this flag yet.  Also, who can verify that they managed to find &lt;i&gt;all&lt;/i&gt; the strings in PHP which represent paths?&lt;/p&gt;
&lt;p&gt;The PHP team was completely missing the point here.  This fix means that path arguments aren't allowed to have embedded NUL bytes.  Other string type arguments are not checked.  They are missing the fact that this &lt;i&gt;isn't&lt;/i&gt; just a path issue.  Rather, as I described before, it's a fundamental mismatch at the language boundary where strings are translated from the host language to C.  However, there seems to be a widespread belief that this can only be exploited in path strings.&lt;/p&gt;
&lt;p&gt;I'm not entirely sure why this is, but I can guess. First off, &amp;quot;poisoned NUL byte&amp;quot; attacks have been popularized by a 1999 &lt;a href="http://www.phrack.org/issues.html?issue=55&amp;amp;id=7#article" class="external"&gt;Phrack article&lt;/a&gt;. This article shows a few attacks, but only the path examples are really convincing.  Of course, another reason is that injecting NUL bytes in path strings really &lt;i&gt;is&lt;/i&gt; the most obvious and practical way to exploit web scripts.&lt;/p&gt;
&lt;p&gt;Recently, however, different NUL byte attacks have been documented. For example, they can be used to truncate &lt;a href="http://blog.portswigger.net/2008/05/null-byte-attacks-are-alive-and-well.html" class="external"&gt;LDAP and SQL queries&lt;/a&gt; and to bypass &lt;a href="http://www.php-security.org/2010/05/13/mops-2010-023-cacti-graph-viewer-sql-injection-vulnerability/index.html" class="external"&gt;regular expression filters on SQL input&lt;/a&gt;, but you could argue these are all examples of failure to escape correctly. I found a more convincing example in the (excellent!) book &lt;a href="http://lcamtuf.coredump.cx/tangled/" class="external"&gt;The Tangled Web&lt;/a&gt;: it contains a one-sentence warning about using HTML sanitation C libraries from other languages.  Also, NUL bytes can sometimes be used to &lt;a href="http://blog.gerhards.net/2010/11/logging-and-c-nul-problem.html" class="external"&gt;hide attacks from log files&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, the most impressive recent exploit is without a doubt &lt;a href="http://thoughtcrime.org/papers/null-prefix-attacks.pdf" class="external"&gt;this common vulnerability&lt;/a&gt; in SSL certificate verification systems.  In an attack, an embedded NUL byte causes a certificate to be accepted for &amp;quot;www.paypal.com&amp;quot;, when the CN (Common Name) section (that is, the server's hostname) actually contains the value &amp;quot;www.paypal.com\0.thoughtcrime.org&amp;quot;.  Certificate authorities generally just accepted this as a valid subdomain of &amp;quot;thoughtcrime.org&amp;quot;, ignoring the NUL byte.  Client programs (like web browsers) tended to use C string comparison functions, which stop at the NUL byte.  Luckily, this was widely reported, and has been fixed in most programs.&lt;/p&gt;
&lt;p&gt;I believe that NUL byte mishandling represents a big and mostly untapped source of vulnerabilities.  High-level languages are gaining popularity over C for client-side programs, but many crucial libraries are still written in C.  This combination means that the problem will grow unless this is structurally fixed in language implementations.&lt;/p&gt;</content>
    <id>tag:more-magic,2012-12-10:/posts/lessons-learned-from-nul-byte-bugs.html</id>
    <published>2012-12-10T21:19:52Z</published>
    <title type="text">Lessons learned from NUL byte bugs</title>
    <updated>2012-12-10T21:19:52Z</updated>
    <link href="https://www.more-magic.net/posts/lessons-learned-from-nul-byte-bugs.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;The &lt;a href="https://www.owasp.org/index.php/Top_10_2010-Main" class="external"&gt;two biggest threats&lt;/a&gt; to the web are caused by the same underlying mistake.  It is time this problem was fixed at its root.  This article will attempt to provide the tools do so.&lt;/p&gt;&lt;a href="#input-sanitation-input-filtering-or-output-escaping"&gt;
&lt;h2 id="input-sanitation-input-filtering-or-output-escaping"&gt;Input sanitation, input filtering or output escaping?&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;The &lt;a href="https://www.owasp.org" class="external"&gt;Open Web Application Security Project (OWASP)&lt;/a&gt; does a great job at educating people and suggesting practical solutions to avoid common weaknesses.  Unfortunately, most security bloggers focus on vulnerabilities rather than the &lt;i&gt;prevention&lt;/i&gt; of attacks, and those that do often give bad advice. For example, common advice is to avoid &lt;a href="http://projects.webappsec.org/w/page/13246920/Cross%20Site%20Scripting" class="external"&gt;XSS (cross-site scripting)&lt;/a&gt; and &lt;a href="http://www.unixwiz.net/techtips/sql-injection.html" class="external"&gt;SQL injection&lt;/a&gt; bugs by &amp;quot;sanitizing&amp;quot; or &amp;quot;validating&amp;quot; input.  Now, by itself this is &lt;i&gt;good&lt;/i&gt; advice.&lt;/p&gt;
&lt;p&gt;Unfortunately, the phrase &amp;quot;sanitize your inputs&amp;quot; is often misunderstood and the advice itself can be misguided.  For example, &lt;a href="http://shiflett.org/articles/foiling-cross-site-attacks" class="external"&gt;Chris Shiflett says&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; If you reject [anything but alphanumerics], Berners-Lee and O'Reilly will be
 rejected, despite being valid last names.   However, this problem is easily
 resolved.  A quick change to also allow single quotes and hyphens is all you
 need to do.  Over time, your input filtering techniques will be perfected.&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;I think this advice is a little unhealthy.  Those &lt;i&gt;are&lt;/i&gt; valid names, and rejecting them will only scare away customers and reinforce the idea that the &amp;quot;security Nazis&amp;quot; are out to inconvenience people. I wish people would place less emphasis on filtering and sanitizing. Citing this XKCD comic has become a cliché, which (while funny) makes it worse:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://imgs.xkcd.com/comics/exploits_of_a_mom.png" /&gt;&lt;/p&gt;
&lt;p&gt;Validating and sanitizing input is good when it refers to parsing input into meaningful values immediately when receiving it, so that you don't, say, get a URL when you are expecting an integer. The horror story of &lt;a href="http://www.codingthewheel.com/archives/radioactive-search-hardened-user-name-for-online-poker" class="external"&gt;ROBCASHFLOW&lt;/a&gt; shows how important input restrictions can be (but see also &lt;a href="http://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/" class="external"&gt;this cautionary list&lt;/a&gt;. Tl;dr: you're doomed either way).&lt;/p&gt;
&lt;p&gt;However, input sanitation will (in general) &lt;i&gt;not&lt;/i&gt; prevent XSS or SQL injection.  The &lt;a href="https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet" class="external"&gt;OWASP XSS prevention &amp;quot;cheat-sheet&amp;quot;&lt;/a&gt; recognizes input validation and sanitation for what it is; a good secondary security measure in a broader &amp;quot;defense in depth&amp;quot; strategy.&lt;/p&gt;
&lt;p&gt;Instead, there are only two &lt;i&gt;correct&lt;/i&gt; ways to prevent &amp;quot;injection&amp;quot; bugs.  The best is often even omitted from advice, which is to avoid the problem entirely (see below).  The other is to escape output. Unfortunately, advice to escape often seems to imply that you should manually call escaping procedures; &amp;quot;just use &lt;tt&gt;mysql_real_escape_string()&lt;/tt&gt;&amp;quot;.  This is a very bad idea; it's tedious, it's easy to forget, it makes code less readable and it requires everyone working on the code to be equally informed about security issues (a great idea, but not very realistic).&lt;/p&gt;
&lt;p&gt;Let's investigate how we can prevent these vulnerabilities &lt;i&gt;easily&lt;/i&gt; and &lt;i&gt;automatically&lt;/i&gt;.  This will help us secure applications in a &lt;i&gt;structural&lt;/i&gt; rather than an &lt;i&gt;ad-hoc&lt;/i&gt; way.&lt;/p&gt;&lt;a href="#the-trouble-with-strings"&gt;
&lt;h2 id="the-trouble-with-strings"&gt;The trouble with strings&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;The underlying problem of all these vulnerabilities is that a tree structure (e.g., the SQL script's AST or the HTML DOM tree) is represented as a string, and user input which should be a node in the tree is inserted into this string.  If this includes characters from the meta-language which describes the tree's structure, it can influence that structure.  Here's an example:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;&amp;lt;p&amp;gt;{username} said the following: {message}&amp;lt;/p&amp;gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;When &lt;tt&gt;message&lt;/tt&gt; is &amp;quot;So you see, if a&amp;lt;b and c&amp;lt;a, then b&amp;gt;c.&amp;quot;, you get output like this (depending on the browser, HTML version and phase of the moon):&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;Math teacher said the following: So you see, if a&lt;b&gt;c.&lt;/b&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This code is simply &lt;i&gt;incorrect&lt;/i&gt;, and this bug will frustrate users like the math teacher.  But this can turn into a security nightmare; any punk can make you look like a fool by &lt;a href="http://davidlynch.org/blog/2011/10/xss-is-fun/" class="external"&gt;making your images dance around&lt;/a&gt;, taking over your users' sessions by &lt;a href="http://www.codinghorror.com/blog/2008/08/protecting-your-cookies-httponly.html" class="external"&gt;stealing cookies&lt;/a&gt;, or do &lt;a href="http://ha.ckers.org/blog/20060718/attacking-applications-via-xss-proxies/" class="external"&gt;much worse&lt;/a&gt;. The underlying reason this nonsense is possible at all is the fact that you are mixing user input strings with HTML.&lt;/p&gt;
&lt;p&gt;In other words, &lt;i&gt;you're performing string surgery on the serialized representation of a tree structure&lt;/i&gt;.  Just stop and think how &lt;b&gt;insane&lt;/b&gt; that really sounds!  Why don't we use &lt;i&gt;real&lt;/i&gt; data types? While researching this topic, I found an insightful article called &amp;quot;&lt;a href="http://acko.net/blog/safe-string-theory-for-the-web/" class="external"&gt;Safe String Theory for the Web&lt;/a&gt;&amp;quot;.  The author has a good grasp on the problem and comes close to the solution, but he never transcends the idea of representing everything as a string.&lt;/p&gt;
&lt;p&gt;Many people don't, so despite the flawed concept, there are several solutions that take string splicing as a given.  For instance, &lt;a href="http://yehudakatz.com/2010/02/01/safebuffers-and-rails-3-0/" class="external"&gt;some frameworks&lt;/a&gt; have a sort of &amp;quot;safe HTML buffers&amp;quot;, which &lt;a href="https://docs.djangoproject.com/en/dev/topics/templates/#automatic-html-escaping" class="external"&gt;automatically HTML-escape&lt;/a&gt; strings.  These solutions don't deal with the &lt;i&gt;context problem&lt;/i&gt; from &amp;quot;Safe String Theory for the Web&amp;quot;. There's only one built-in string type, and making it context-aware is &lt;a href="http://blog.astrumfutura.com/2012/06/automatic-output-escaping-in-php-and-the-real-future-of-preventing-cross-site-scripting-xss/" class="external"&gt;extremely hard&lt;/a&gt;, maybe even impossible.  Strongly typed languages have an &lt;a href="http://www.yesodweb.com/book/shakespearean-templates" class="external"&gt;advantage&lt;/a&gt; here, though!&lt;/p&gt;
&lt;p&gt;Representing HTML as a tree helps preventing injection bugs, and has other advantages over automatic escaping.  For example, we need to worry less about generating invalid HTML; our output is always guaranteed to be &lt;a href="http://www.w3.org/TR/xml/#sec-well-formed" class="external"&gt;well-formed&lt;/a&gt;. The essence of an XSS attack is that it breaks up your document structure and re-shapes it.  These are just two sides to the same coin: By taking control of the HTML's shape, XSS is also avoided.&lt;/p&gt;
&lt;p&gt;There's another, more insidious problem with splicing HTML strings, which I haven't seen discussed much either.  It's another &lt;i&gt;context problem&lt;/i&gt;; if your complex web application contains many &amp;quot;helper&amp;quot; functions, it becomes very hard to keep track of which helper functions accept HTML and which accept text.  For example, is the following PHP function safe?&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight php-language"&gt;function render_latest_topicslist() {
  $out = &amp;#x27;&amp;#x27;;
  foreach(Forum::latestPosts(10) as $topic) {
    $link = render_link(&amp;#x27;forum/show/&amp;#x27;.(int)$topic[&amp;#x27;id&amp;#x27;], $topic[&amp;#x27;title&amp;#x27;]);
    $out .= &amp;quot;&amp;lt;li&amp;gt;{$link}&amp;lt;/li&amp;gt;&amp;quot;;
  }
  return &amp;quot;&amp;lt;ul id=\&amp;quot;latest-topics\&amp;quot;&amp;gt;{$out}&amp;lt;/ul&amp;gt;&amp;quot;;
}&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This is (of course) a trick question.  Consider:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight php-language"&gt;$dest_url = ... some URL ...
$dest = htmlspecialchars($dest_url, ENT_QUOTES, &amp;#x27;UTF-8&amp;#x27;);
echo render_link($dest_url, &amp;quot;&amp;lt;span&amp;gt;Go to &amp;lt;em&amp;gt;{$dest}&amp;lt;/em&amp;gt; directly.&amp;lt;/span&amp;gt;&amp;quot;);&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Either this second example is wrong and the tags will come out literally (i.e., as &lt;tt&gt;&amp;amp;lt;span&amp;amp;gt;&lt;/tt&gt;...&lt;tt&gt;&amp;amp;lt;/span&amp;amp;gt;&lt;/tt&gt; in the HTML source), or the first example was wrong and you have an injection bug. You can't tell without consulting &lt;tt&gt;render_link&lt;/tt&gt;'s API documentation or implementation.  With many helper procedures, how can you keep track of which accept fully formed HTML and which escape their input? What happens when a function which auto-encodes suddenly needs to be changed to accept HTML?&lt;/p&gt;
&lt;p&gt;This style of programming results in &lt;i&gt;ad-hoc security&lt;/i&gt;.  You add escaping in just the right places, decided on a case-by-case basis. This is unsafe by default; you must remember to escape, which makes it error-prone.  It's also hard to spot mistakes in this style.  The alternative to ad-hoc security is &lt;i&gt;structural security&lt;/i&gt;: a style which makes it virtually impossible to write insecure code by accident, thus eliminating entire classes of vulnerabilities.&lt;/p&gt;
&lt;p&gt;For example, in PHP we could use the &lt;a href="http://nl.php.net/manual/en/book.dom.php" class="external"&gt;DOM&lt;/a&gt; library to represent an HTML tree:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight php-language"&gt;function get_latest_topicslist($document) {
  $ul = $document-&amp;gt;createElement(&amp;#x27;ul&amp;#x27;);
  $ul-&amp;gt;setAttribute(&amp;#x27;id&amp;#x27;, &amp;#x27;latest-topics&amp;#x27;);

  foreach(Forum::latestPosts(10) as $topic) {
    $title = $document-&amp;gt;createTextNode($topic[&amp;#x27;title&amp;#x27;]);
    $link = get_link($document, &amp;#x27;forum/show/&amp;#x27;.(int)$topic[&amp;#x27;id&amp;#x27;], $title);

    $li = $document-&amp;gt;createElement(&amp;#x27;li&amp;#x27;);
    $li-&amp;gt;appendChild($link);
    $ul-&amp;gt;appendChild($li);
  }
  return $ul;
}&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;And the second example:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight php-language"&gt;$contents = $document-&amp;gt;createElement(&amp;#x27;span&amp;#x27;);
$contents-&amp;gt;appendChild($document-&amp;gt;createTextNode(&amp;#x27;Go to &amp;#x27;));
$em = $document-&amp;gt;createElement(&amp;#x27;em&amp;#x27;);
$em-&amp;gt;appendChild($document-&amp;gt;createTextNode($dest));
$contents-&amp;gt;appendChild($em);
$contents-&amp;gt;appendChild($document-&amp;gt;createTextNode(&amp;#x27; directly.&amp;#x27;));
$link = get_link($document, $dest_url, $contents);&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Unfortunately, this code is very verbose.  The stuff that really matters gets lost in the noise of DOM manipulation.  The advantage is that this is safe; text content cannot influence the tree structure, since the type of every function argument is enforced to be a DOM object and string contents are automatically XML-encoded on output.&lt;/p&gt;&lt;a href="#language-design-to-the-rescue"&gt;
&lt;h2 id="language-design-to-the-rescue"&gt;Language design to the rescue!&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Language design can help a great deal to improve security. For example, domain-specific languages like &lt;a href="/posts/lispy-dsl-sxml.html" class="internal"&gt;SXML&lt;/a&gt; and &lt;a href="/posts/lispy-dsl-ssql.html" class="internal"&gt;SSQL&lt;/a&gt; can save the programmer from having to remember to escape while writing most &amp;quot;normal&amp;quot;, day-to-day code. This frees precious brain cycles to think about more essential things, like the program's purpose.  Here's the example again, using SXML:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;latest-topics-list&lt;/span&gt;)&lt;/span&gt;
  `&lt;span class="paren2"&gt;(&lt;span class="default"&gt;ul &lt;span class="paren3"&gt;(&lt;span class="default"&gt;@ &lt;span class="paren4"&gt;(&lt;span class="default"&gt;id &lt;span class="string"&gt;&amp;quot;latest-topics&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
       ,&lt;span class="paren3"&gt;(&lt;span class="default"&gt;map &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;lambda&lt;/span&gt;&lt;/i&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;topic&lt;/span&gt;)&lt;/span&gt;
               `&lt;span class="paren5"&gt;(&lt;span class="default"&gt;li ,&lt;span class="paren6"&gt;(&lt;span class="default"&gt;make-link `&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;forum&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;show&amp;quot;&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;alist-ref &amp;#x27;id topic&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                                &lt;span class="paren1"&gt;(&lt;span class="default"&gt;alist-ref &amp;#x27;title topic&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
             &lt;span class="paren3"&gt;(&lt;span class="default"&gt;forum-latest-posts 10&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;And the second example:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;make-link destination-url `&lt;span class="paren2"&gt;(&lt;span class="default"&gt;span &lt;span class="string"&gt;&amp;quot;Go to &amp;quot;&lt;/span&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;em ,destination&lt;/span&gt;)&lt;/span&gt; &lt;span class="string"&gt;&amp;quot; directly.&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This code is safe from XSS, like the PHP DOM example.  However, this code is (to a Schemer) just as readable as the naive PHP version. And, most importantly, the safety is achieved without any effort from the programmer.&lt;/p&gt;
&lt;p&gt;This shows the immense safety and security advantages that can be gained from language design.  Of course, this isn't completely foolproof: We still need to ensure URIs used in &lt;tt&gt;href&lt;/tt&gt; attributes have an allowed scheme like &lt;tt&gt;http:&lt;/tt&gt; or &lt;tt&gt;ftp:&lt;/tt&gt; and not, say, &lt;tt&gt;javascript:&lt;/tt&gt;.  Note that input filtering and sanitation can help in situations like these!  Also, just like with automatic escaping, strings in sub-languages (like JS or CSS) aren't automatically escaped.  However, there is less &amp;quot;magic&amp;quot; involved; this is a representation for HTML, so it's obvious that only HTML meta-characters will be encoded.  If we're also using DSLs for sub-languages, this auto-escaping effect can be nested, solving the &amp;quot;context problem&amp;quot; in a way automatic escaping cannot.&lt;/p&gt;
&lt;p&gt;SXML rewards programmers for writing safe code by making it look clean, concise, and easy to write.  String splicing looks ugly and verbose in Scheme.  In plain PHP this looks clean and simple, while DOM manipulation looks ugly.  This subtly guides programmers into writing unsafe code.  However, there are some PHP libraries that make safe code look clean.  For example, Drupal has a &amp;quot;&lt;a href="http://drupal.org/node/751826" class="external"&gt;Forms API&lt;/a&gt;&amp;quot;.  It's a little ugly, but it's idiomatic in Drupal, which means code that uses it is considered cleaner than code that doesn't.  Facebook is another attractive target for attackers, so they &lt;i&gt;had&lt;/i&gt; to come up with a structural solution.  Their solution is a &lt;a href="https://www.facebook.com/notes/facebook-engineering/xhp-a-new-way-to-write-php/294003943919" class="external"&gt;language extension called XHP&lt;/a&gt; which adds native support for HTML literals.&lt;/p&gt;
&lt;p&gt;These solutions are all specific to some codebase, not part of basic PHP.  A framework or an existing codebase has &amp;quot;default&amp;quot; libraries, but when writing from scratch most programmers prefer to use what's available in the base language.  This means a language should only include libraries that are safe by default.  Otherwise, alternative safe libraries have to compete with the standard ones, which is an unfair disadvantage!&lt;/p&gt;&lt;a href="#sidestepping-the-sql-injection-problem-entirely"&gt;
&lt;h2 id="sidestepping-the-sql-injection-problem-entirely"&gt;Sidestepping the SQL injection problem entirely&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Even though it's possible to write safe code in almost any language if you try hard enough, the basic design of a language itself subtly influences how people will program in it &lt;i&gt;by default&lt;/i&gt;.  Consider the following example, using the &lt;a href="https://bitbucket.org/ged/ruby-pg/wiki/Home" class="external"&gt;Ruby PG gem&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight ruby-language"&gt;&lt;span class="comment"&gt;# This code is vulnerable to SQL injection if the variables store user input
&lt;/span&gt;res = db.query&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;SELECT first, last FROM users &amp;quot;&lt;/span&gt;
               &lt;span class="string"&gt;&amp;quot;WHERE login = &amp;#x27;&lt;/span&gt;#{login}&lt;span class="string"&gt;&amp;#x27; &amp;quot;&lt;/span&gt;
               &lt;span class="string"&gt;&amp;quot;AND customer = &amp;#x27;&lt;/span&gt;#{customer}&lt;span class="string"&gt;&amp;#x27; &amp;quot;&lt;/span&gt;
               &lt;span class="string"&gt;&amp;quot;AND department = &amp;#x27;&lt;/span&gt;#{department}&lt;span class="string"&gt;&amp;#x27;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Here we're using &lt;i&gt;string interpolation&lt;/i&gt;, which is the expansion of variable names within a string.  We saw this before, in PHP, but in Ruby you can drop back to the &lt;i&gt;full&lt;/i&gt; language, which makes the safe solution a little easier to write:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight ruby-language"&gt;&lt;span class="comment"&gt;# This code is safe
&lt;/span&gt;res = db.query&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;SELECT first, last FROM users &amp;quot;&lt;/span&gt;
               &lt;span class="string"&gt;&amp;quot;WHERE login = &amp;#x27;&lt;/span&gt;#{db.escape_string&lt;span class="paren2"&gt;(&lt;span class="default"&gt;login&lt;/span&gt;)&lt;/span&gt;}&lt;span class="string"&gt;&amp;#x27; &amp;quot;&lt;/span&gt;
               &lt;span class="string"&gt;&amp;quot;AND customer = &amp;#x27;&lt;/span&gt;#{db.escape_string&lt;span class="paren2"&gt;(&lt;span class="default"&gt;customer&lt;/span&gt;)&lt;/span&gt;}&lt;span class="string"&gt;&amp;#x27; &amp;quot;&lt;/span&gt;
               &lt;span class="string"&gt;&amp;quot;AND department = &amp;#x27;&lt;/span&gt;#{db.escape_string&lt;span class="paren2"&gt;(&lt;span class="default"&gt;department&lt;/span&gt;)&lt;/span&gt;}&lt;span class="string"&gt;&amp;#x27;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Still, it looks uglier than the first example.&lt;/p&gt;
&lt;p&gt;The documentation says the &lt;tt&gt;escape_string&lt;/tt&gt; method is considered &lt;a href="http://deveiate.org/code/pg/PG/Connection.html#method-c-escape_string" class="external"&gt;deprecated&lt;/a&gt;. That's because sidestepping the problem entirely is much smarter than escaping.  This is done by passing the user-supplied values completely separate (&amp;quot;out of band&amp;quot;) from the SQL command string.  This way, the data can't possibly influence the structure of the command.  They are kept separate even in the network protocol, so it is enforced all the way up into the server.  As an added bonus, this is only &lt;i&gt;slightly&lt;/i&gt; more verbose than the naive version:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight ruby-language"&gt;&lt;span class="comment"&gt;# This code is even safer
&lt;/span&gt;res = db.query&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;SELECT first, last FROM users &amp;quot;&lt;/span&gt;
               &lt;span class="string"&gt;&amp;quot;WHERE login = $1 AND customer = $2 AND department = $3&amp;quot;&lt;/span&gt;,
	       &lt;span class="paren2"&gt;[&lt;span class="default"&gt;login, customer, department&lt;/span&gt;]&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This scales only to about a dozen parameters.  With more, it becomes hard to mentally map the correct parameter to the correct position.  A DSL can do this automatically for you.  For example, Microsoft's &lt;a href="http://msdn.microsoft.com/en-us/library/bb425822.aspx" class="external"&gt;LinqToSQL&lt;/a&gt; language extension seems to do this.  SSQL currently auto-escapes, but it could transparently be changed to use positional parameters.&lt;/p&gt;&lt;a href="#pervasive-insecurity-through-bad-design"&gt;
&lt;h2 id="pervasive-insecurity-through-bad-design"&gt;Pervasive (in)security through (bad) design&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;I'm not a native English speaker, so I looked up the word &amp;quot;interpolation&amp;quot; on  &lt;a href="http://www.m-w.com/dictionary/interpolate" class="external"&gt;Merriam-Webster&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; interpolate, transitive verb:
 To alter or corrupt (as a text) by inserting new or foreign matter&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;To corrupt, indeed!&lt;/p&gt;
&lt;p&gt;Interpolation of user-supplied strings is &lt;i&gt;rarely&lt;/i&gt; correct, and it puts almost any conceivable safe API at a disadvantage by making the wrong thing easier and shorter to write than the right thing. Beginners, unaware of the security risks, will try to use this &amp;quot;neat feature&amp;quot;.  It's put in there for a reason, right?  Some people &lt;i&gt;are&lt;/i&gt; trying to &lt;a href="http://google-caja.googlecode.com/svn/changes/mikesamuel/string-interpolation-29-Jan-2008/trunk/src/js/com/google/caja/interp/index.html#-autogen-id-1" class="external"&gt;fix string interpolation&lt;/a&gt;, which is a noble goal but I wouldn't expect this to be adopted as the &amp;quot;native&amp;quot; string interpolation mechanism in a language any time soon.&lt;/p&gt;
&lt;p&gt;The Ruby examples show the importance of good documentation and library design.  The docs pointed us in the right direction by marking the &lt;tt&gt;escape_string&lt;/tt&gt; method as deprecated.  Its good design is more apparent when contrasting it with the &lt;a href="http://www.tmtm.org/en/mysql/ruby/" class="external"&gt;MySQL gem&lt;/a&gt;.  This has no support for positional arguments in &lt;tt&gt;query&lt;/tt&gt;, having only &lt;tt&gt;escape_string&lt;/tt&gt; and &lt;tt&gt;prepare&lt;/tt&gt;.  The latter allows you to pass parameters separately, but it conflates value separation with statement caching and has an unwieldy API.  Finally, the docs are quite sparse.  Taken together, this all gently nudges developers into the direction of string interpolation by making that the easiest way to do it.  Much of this is due to the design of MySQL's wire protocol, which dictates the API of the C library, which in turn guides the design of &amp;quot;high-level&amp;quot; libraries built on top of it.&lt;/p&gt;
&lt;p&gt;I think high-level libraries should strive to abstract away unsafe or painful aspects of the lower levels.  For example, the Chicken &lt;a href="http://wiki.call-cc.org/eggref/4/mysql-client" class="external"&gt;MySQL-client egg&lt;/a&gt; emulates value separation:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;conn &lt;span class="paren2"&gt;(&lt;span class="default"&gt;string-append &lt;span class="string"&gt;&amp;quot;SELECT first, last FROM users &amp;quot;&lt;/span&gt;
                     &lt;span class="string"&gt;&amp;quot;WHERE login = &amp;#x27;?login&amp;#x27; &amp;quot;&lt;/span&gt;
                     &lt;span class="string"&gt;&amp;quot;AND customer = &amp;#x27;?cust&amp;#x27; &amp;quot;&lt;/span&gt;
                     &lt;span class="string"&gt;&amp;quot;AND department = &amp;#x27;?dept&amp;#x27;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
      `&lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;?login . ,login&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;?cust . ,customer&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;?dept . ,department&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Ruby's MySQL gem could easily have done this, but they chose to restrict themselves to making a thin layer which maps closely to the C library.&lt;/p&gt;
&lt;p&gt;Not all is lost with crappy libraries: Abstractions can solve such problems at an even higher level.  Rails can safely pass query parameters via &lt;a href="https://github.com/rails/arel" class="external"&gt;Arel&lt;/a&gt;, in a database-independent way, even though MySQL is one of the back-ends. This is true for &lt;a href="http://www.sqlalchemy.org/" class="external"&gt;SQLAlchemy&lt;/a&gt;, &lt;a href="http://nl3.php.net/manual/en/pdostatement.bindvalue.php" class="external"&gt;PDO&lt;/a&gt; and many others.&lt;/p&gt;&lt;a href="#other-examples"&gt;
&lt;h2 id="other-examples"&gt;Other examples&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;This section will show more examples of the same bug.  They can all be &lt;i&gt;structurally&lt;/i&gt; solved in two simple ways: Automatic escaping (by using proper data structures) or passing data separately from the control language.  But let's start with one where this won't work :)&lt;/p&gt;&lt;a href="#poisoned-nul-bytes"&gt;
&lt;h3 id="poisoned-nul-bytes"&gt;Poisoned NUL bytes&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;As you may know, strings in the C language are pointers to a character array terminated by a NUL (ASCII 0) byte.  Many other languages represent strings as a pointer plus a length, allowing NUL &amp;quot;characters&amp;quot; to simply occur in strings, with no special meaning.&lt;/p&gt;
&lt;p&gt;This representational mismatch can be a problem when calling C functions from these languages.  In many cases, a C character array of the length of the string plus 1 is allocated, the string contents are copied from the &amp;quot;native&amp;quot; string to the array and a NUL byte is inserted at the end.  This causes a &lt;i&gt;reinterpretation&lt;/i&gt; of the string's value if it contains a NUL byte, which opens up a potential vulnerability to a &lt;a href="http://www.hakipedia.com/index.php/Poison_Null_Byte" class="external"&gt;&amp;quot;poisoned&amp;quot; NUL byte attack&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let's look at a toy example in Chicken Scheme:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; greeting &lt;span class="string"&gt;&amp;quot;hello&lt;/span&gt;&lt;span class="string"&gt;\x&lt;/span&gt;&lt;span class="string"&gt;00, world!&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; calculate-length-in-c
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;foreign-lambda int &lt;span class="string"&gt;&amp;quot;strlen&amp;quot;&lt;/span&gt; c-string&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;print &lt;span class="string"&gt;&amp;quot;Scheme says: &amp;quot;&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;string-length greeting&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;print &lt;span class="string"&gt;&amp;quot;C says: &amp;quot;&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;calculate-length-in-c greeting&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;As far as Scheme is concerned, the NUL byte is perfectly legal and the string's length is 14, but for C, the string ends after &lt;tt&gt;hello&lt;/tt&gt;, which makes for a length of 5.  There is no way in C to &amp;quot;escape&amp;quot; NUL bytes, and we can't sidestep it here, either.  Our only option is to raise an error:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; Scheme says: 14
 
 Error: (##sys#make-c-string) cannot represent string with
    NUL bytes as C string: &amp;quot;hello\x00, world!&amp;quot;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This is a good example of structural security; it doesn't matter whether the programmer is caffeine-deprived, on a tight deadline or simply unaware of this particular vulnerability.  He or she is protected from accidentally making this mistake because it's handled at the boundary between C and Scheme, which is exactly where it &lt;i&gt;should&lt;/i&gt; be handled.&lt;/p&gt;&lt;a href="#http-response-splittingheader-injection"&gt;
&lt;h3 id="http-response-splittingheader-injection"&gt;HTTP response splitting/Header injection&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;&lt;a href="https://www.owasp.org/index.php/HTTP_Response_Splitting" class="external"&gt;HTTP response splitting&lt;/a&gt; and HTTP header injection are two closely related attacks, based on a single underlying weakness.&lt;/p&gt;
&lt;p&gt;The idea is simple: HTTP (response) headers are separated by a CRLF combination.  If user input ends up in a header (like in a &lt;tt&gt;Location&lt;/tt&gt; header for a redirect), this can allow an attacker to split a header in two by putting a separator in it. Let's say that &lt;tt&gt;http://example.com/foo&lt;/tt&gt; gets redirected to &lt;tt&gt;http://example.com/blabla?q=foo&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;An attacker can trick someone (or their browser) into following this link (%0d%0a is an URI-encoded CRLF pair):&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; http://www.example.com/abc%0d%0aSet-Cookie%3a%20SESSION%3dwhatever-i-want&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This could cause the victim's session cookie for example.com to be overwritten:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; Location: http://www.example.com/blabla?q=abc
 Set-Cookie: SESSION=whatever-i-want&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This is a &lt;a href="https://www.owasp.org/index.php/Session_fixation" class="external"&gt;session fixation&lt;/a&gt; attack.  For this particular bug, the real solution is of course to properly percent-encode the destination URI, but the &lt;i&gt;general&lt;/i&gt; solution can be as simple as disallowing newlines in the header-setting mechanism (e.g., &lt;a href="http://php.net/releases/5_1_2.php" class="external"&gt;PHP does this since 5.1.2&lt;/a&gt;). Doing it in the only procedure which is capable of emitting headers is a structurally secure approach, but it won't protect against all attacks.&lt;/p&gt;
&lt;p&gt;For example, even if we disallow newlines it is still possible to set a &lt;i&gt;parameter&lt;/i&gt; (attribute) or a &lt;i&gt;second value&lt;/i&gt; for a header, splitting it with a semicolon or a comma, respectively:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; Accept: text/html;q=0.5, text/{user-type}&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;If this is done unsafely, extra content-types can be added.  They can even be given preference:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; Accept: text/html;q=0.5, text/plain;q=0.1, application/octet-stream;q=1.0&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Protecting against these sorts of attacks can only be done with libraries which know each header's syntax and use rich objects to represent them.  This approach is taken by &lt;a href="http://wiki.call-cc.org/eggref/4/intarweb" class="external"&gt;intarweb&lt;/a&gt; and Guile's &lt;a href="http://www.gnu.org/software/guile/manual/html_node/HTTP-Headers.html#HTTP-Headers" class="external"&gt;HTTP library&lt;/a&gt;, and is similar to representing HTML as a (DOM) tree. I'm not aware of any other libraries which use fully parsed &amp;quot;objects&amp;quot; to represent HTTP header values.&lt;/p&gt;&lt;a href="#running-subprocesses"&gt;
&lt;h3 id="running-subprocesses"&gt;Running subprocesses&lt;/h3&gt;&lt;/a&gt;
&lt;p&gt;For some reason, often people use a procedure like &lt;tt&gt;system()&lt;/tt&gt; to invoke subprocesses.  It's the most convenient way to quickly run a program just like you would from the command line.  It will pass this string to the Unix shell, which expands globs (&amp;quot;wildcards&amp;quot;) and runs the program:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;system &lt;span class="paren2"&gt;(&lt;span class="default"&gt;sprintf &lt;span class="string"&gt;&amp;quot;echo &lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;~A&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt; input&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;  &lt;span class="comment"&gt;;; UNSAFE:   byebye files&amp;quot;; rm -rf / &amp;quot; &lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Several languages have specialized syntax for invoking the shell and putting the output in a string using backticks, e.g., &lt;tt&gt;`echo hi`&lt;/tt&gt;. The &lt;i&gt;really&lt;/i&gt; bad part is that string interpolation is supported within the backtick operator, e.g., &lt;tt&gt;`echo Hi, &amp;quot;{$name}&amp;quot;`&lt;/tt&gt;.  This is dangerous because the shell is yet another interpreter with its own language, and we've learned by now that we shouldn't embed user input directly into a sublanguage.  Here too, string interpolation makes the &lt;i&gt;wrong thing&lt;/i&gt; very convenient, which increases the risk of abuse and bugs.  After all, spaces and quotes are perfectly legal inside filenames, but when used with unsafely interpolated parameters, they will cause errors.&lt;/p&gt;
&lt;p&gt;It is possible to escape shell arguments, but it's very tricky: no two shells provide exactly the same command language with the same meta-characters.  Is your &lt;tt&gt;/bin/sh&lt;/tt&gt; really &lt;a href="http://linux.die.net/man/1/sh" class="external"&gt;bash&lt;/a&gt;, &lt;a href="http://gondor.apana.org.au/~herbert/dash/" class="external"&gt;dash&lt;/a&gt;, &lt;a href="http://netbsd.gw.com/cgi-bin/man-cgi?sh++NetBSD-current" class="external"&gt;ash&lt;/a&gt;, &lt;a href="http://www.opensolarisforum.org/man/man1/sh.html" class="external"&gt;ksh&lt;/a&gt; or something else?  It is even &lt;a href="http://pubs.opengroup.org/onlinepubs/009695399/functions/system.html" class="external"&gt;unspecified&lt;/a&gt; whether the &lt;tt&gt;sh&lt;/tt&gt; used is &lt;tt&gt;/bin/sh&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;However, a better approach is often available.  Many programming languages offer an interface to one or more members of the POSIX &lt;tt&gt;exec()&lt;/tt&gt; function family.  These allow passing the arguments to the program in a separate array, and they don't go through the shell to invoke the program at all.  This is faster and a lot more secure.&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;use posix&lt;/span&gt;)&lt;/span&gt;
&lt;span class="comment"&gt;;; Accepts a list of arguments:
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;process &lt;span class="string"&gt;&amp;quot;echo&amp;quot;&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;list &lt;span class="string"&gt;&amp;quot;Hello, &amp;quot;&lt;/span&gt; first-name &lt;span class="string"&gt;&amp;quot; &amp;quot;&lt;/span&gt; last-name&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;By sidestepping the problem we've made it simpler, shorter than the system call above and safer, which is our goal.  In languages with string interpolation this will probably be slightly more verbose than the &lt;tt&gt;system()&lt;/tt&gt; version.&lt;/p&gt;
&lt;p&gt;There is one small problem: by eliminating a call to the shell, we've also lost the ability to easily construct pipelines.  This can be done by calling several procedures, but this is &lt;a href="http://julialang.org/blog/2012/03/shelling-out-sucks/" class="external"&gt;way more complicated&lt;/a&gt; than it is in the shell language.  The obvious solution to that is to design a safe DSL.  This is what the Scheme Shell does with its &lt;a href="http://www.scsh.net/docu/html/man-Z-H-3.html#node_chap_2" class="external"&gt;notation&lt;/a&gt; for UNIX pipelines:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="comment"&gt;;; This will echo back the input, regardless of &amp;quot;special&amp;quot; characters
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; output &lt;span class="paren2"&gt;(&lt;span class="default"&gt;run/string &lt;span class="paren3"&gt;(&lt;span class="default"&gt;| &lt;span class="paren4"&gt;(&lt;span class="default"&gt;echo input&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;caesar 5&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;caesar 21&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="paren1"&gt;(&lt;span class="default"&gt;display output&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Almost as convenient as the backtick operator, but without its dangers.&lt;/p&gt;&lt;a href="#summary"&gt;
&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Language design can help us write applications which are structurally secure.  We should strive to make writing the right thing easier than the wrong thing so that even naively written, quick and dirty code has some chance of being safe.  To reach this goal, we can use the following approaches, in roughly decreasing order of safety:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;Sidestep&amp;quot; the issue by keeping data separated from commands.&lt;/li&gt;
&lt;li&gt;Represent data in proper data structures, not strings.  On output, escape where needed.&lt;/li&gt;
&lt;li&gt;Use &amp;quot;safe buffers&amp;quot; which auto-escape concatenated strings.&lt;/li&gt;
&lt;li&gt;If escaping or separation is impossible, raise an error on bad data.&lt;/li&gt;
&lt;li&gt;If all else fails you can escape manually, but use coding conventions that &lt;a href="http://www.joelonsoftware.com/articles/Wrong.html" class="external"&gt;make unsafe code stand out&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;These approaches are your first line of defense.  Besides using these, you should also filter and sanitize your input.  Just don't mistake that as the fix for injection vulnerabilities!&lt;/p&gt;
&lt;p&gt;This is the positive advice I can give you.  The negative advice is simply to avoid building language or library features which make unsafe code easier to write than safe code.  An example of such a feature is string interpolation, which causes more harm than good.&lt;/p&gt;</content>
    <id>tag:more-magic,2012-09-23:/posts/structurally-fixing-injection-bugs.html</id>
    <published>2012-09-23T14:10:49Z</published>
    <title type="text">Structurally fixing injection bugs</title>
    <updated>2012-09-23T14:10:49Z</updated>
    <link href="https://www.more-magic.net/posts/structurally-fixing-injection-bugs.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;Today we'll look at an old, experimental DSL of my own design.  I've always referred to it as a failed experiment, but perhaps it's really a successful experiment, because it helped me figure out why this type of DSL doesn't work too well.  Whatever the status, I'll use it as an example of what makes a &lt;i&gt;bad&lt;/i&gt; DSL.&lt;/p&gt;
&lt;p&gt;The DSL in question is &lt;a href="http://wiki.call-cc.org/eggref/4/ssql" class="external"&gt;SSQL&lt;/a&gt;, a way of embedding SQL as S-expressions into Scheme code. Interestingly, it seems I had a bad feeling about it from the start; the &lt;a href="https://bugs.call-cc.org/changeset/10693/release/3/ssql/trunk" class="external"&gt;initial commit&lt;/a&gt; had the following message:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; Add another doomed project - ssql&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;It turned out not to be &lt;i&gt;completely&lt;/i&gt; doomed, because &lt;a href="http://ceaude.twoticketsplease.de/" class="external"&gt;Moritz Heidkamp&lt;/a&gt; has kindly taken over maintenance and has been improving and polishing the library. I might even use it again for my own projects if I ever get tired of working directly with SQL.&lt;/p&gt;&lt;a href="#scoped-access"&gt;
&lt;h2 id="scoped-access"&gt;Scoped access&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;For my day job I used to write a lot of Rails code, and I got tired of the restrictions in &lt;tt&gt;ActiveRecord&lt;/tt&gt;.  I have to mention that this was in the days before &lt;a href="https://github.com/rails/arel" class="external"&gt;Arel&lt;/a&gt;, which is a great improvement in the way you can use custom queries in Rails.&lt;/p&gt;
&lt;p&gt;With &lt;tt&gt;ActiveRecord&lt;/tt&gt;, you could write code that would automatically prevent users from accessing things they shouldn't be able to access with the &lt;a href="http://casperfabricius.com/site/2008/03/16/scoped-access/" class="external"&gt;scoped_access&lt;/a&gt; plugin.  This allowed you to write things in your controller like the following:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight ruby-language"&gt;scoped_access Customer

&lt;span class="symbol"&gt;def&lt;/span&gt; method_scoping
  ScopedAccess::ClassScoping.new&lt;span class="paren1"&gt;(&lt;span class="default"&gt;Customer, &lt;span class="keyword"&gt;:user&lt;/span&gt; =&amp;gt; &lt;span class="paren2"&gt;{&lt;span class="default"&gt;&lt;span class="keyword"&gt;:id&lt;/span&gt; =&amp;gt; current_user.id&lt;/span&gt;}&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
&lt;span class="symbol"&gt;end&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;I don't recall exactly how it worked, but when you had a complex query, this could cause clashes when the same table was joined in twice, especially if the condition was complex.  In different situations, different queries could be generated.  Back then, you also needed to know internally-generated join aliases in order to scope related tables.  Remember, this was quite a while ago, and I was a bit of a newbie and had been programming Ruby and Rails for only a year or two. There may have been better ways to do this even then.&lt;/p&gt;
&lt;p&gt;In any case, this scoping problem annoyed me no end and I &lt;i&gt;knew&lt;/i&gt; there had to be a better way.  It was obvious that if you represent the query in a more complex data structure than a simple string, you can easily fetch all the references to a particular table (even if it is aliased), and add some scoping to it.  This could be done even if it required the addition of joins, and even if those tables were already joined under arbitrary names, as long as you would &lt;a href="https://en.wikipedia.org/wiki/Lambda_calculus#.CE.B1-conversion" class="external"&gt;alpha-rename&lt;/a&gt; all aliases to avoid clashes with user-created aliases.&lt;/p&gt;
&lt;p&gt;Here's an example of the SSQL syntax.  This example is based on a toy data model for an IMDB-clone with films, actors and their roles in them:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&amp;#x27;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;select &lt;span class="paren2"&gt;(&lt;span class="default"&gt;columns &lt;span class="paren3"&gt;(&lt;span class="default"&gt;col actors id firstname lastname&lt;/span&gt;)&lt;/span&gt;
                  &lt;span class="paren3"&gt;(&lt;span class="default"&gt;col roles character movie_id&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren2"&gt;(&lt;span class="default"&gt;from actors roles&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren2"&gt;(&lt;span class="default"&gt;where &lt;span class="paren3"&gt;(&lt;span class="default"&gt;and &lt;span class="paren4"&gt;(&lt;span class="default"&gt;= &lt;span class="paren5"&gt;(&lt;span class="default"&gt;col actors firstname&lt;/span&gt;)&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Bruce&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                     &lt;span class="paren4"&gt;(&lt;span class="default"&gt;= &lt;span class="paren5"&gt;(&lt;span class="default"&gt;col actors lastname&lt;/span&gt;)&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Campbell&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
		     &lt;span class="paren4"&gt;(&lt;span class="default"&gt;= &lt;span class="paren5"&gt;(&lt;span class="default"&gt;col actors id&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;col roles actor_id&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The regular SQL equivalent of this:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; SELECT actors.id, actors.firstname, actors.lastname,
        roles.character, roles.movie_id
 FROM actors, roles
 WHERE actors.firstname = 'Bruce'
   AND actors.lastname = 'Campbell'
   AND actors.id = roles.actor_id;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The SSQL for column selection can be a little ugly or verbose, so it's also allowed to specify columns with a dot instead of the &lt;tt&gt;col&lt;/tt&gt; form (probably a mistake, complicating the DSL design):&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&amp;#x27;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;select &lt;span class="paren2"&gt;(&lt;span class="default"&gt;columns actors.id actors.firstname actors.lastname
                  roles.character roles.movie_id&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren2"&gt;(&lt;span class="default"&gt;from actors roles&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren2"&gt;(&lt;span class="default"&gt;where &lt;span class="paren3"&gt;(&lt;span class="default"&gt;and &lt;span class="paren4"&gt;(&lt;span class="default"&gt;= actors.firstname &lt;span class="string"&gt;&amp;quot;Bruce&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                     &lt;span class="paren4"&gt;(&lt;span class="default"&gt;= actors.lastname &lt;span class="string"&gt;&amp;quot;Campbell&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
		     &lt;span class="paren4"&gt;(&lt;span class="default"&gt;= actors.id roles.actor_id&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;tt&gt;columns&lt;/tt&gt; &amp;quot;noise word&amp;quot; is still required, because that makes it easier to walk the expression and programmatically manipulate it.  In any case, scoping a table is easy, even for arbitrarily complex cases:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;query
        &amp;#x27;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;select &lt;span class="paren5"&gt;(&lt;span class="default"&gt;columns actors.firstname actors.lastname
                          roles.character movies.title&lt;/span&gt;)&lt;/span&gt;
                 &lt;span class="paren5"&gt;(&lt;span class="default"&gt;from &lt;span class="paren6"&gt;(&lt;span class="default"&gt;join left
                             &lt;span class="paren1"&gt;(&lt;span class="default"&gt;join left actors
                                   &lt;span class="paren2"&gt;(&lt;span class="default"&gt;join inner roles &lt;span class="paren3"&gt;(&lt;span class="default"&gt;as movies m2&lt;/span&gt;)&lt;/span&gt;
                                         &lt;span class="paren3"&gt;(&lt;span class="default"&gt;on &lt;span class="paren4"&gt;(&lt;span class="default"&gt;and &lt;span class="paren5"&gt;(&lt;span class="default"&gt;= m2.id roles.movie_id&lt;/span&gt;)&lt;/span&gt;
                                                  &lt;span class="paren5"&gt;(&lt;span class="default"&gt;&amp;gt; m2.year 2000&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                                   &lt;span class="paren2"&gt;(&lt;span class="default"&gt;on &lt;span class="paren3"&gt;(&lt;span class="default"&gt;= roles.actor_id actors.id&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                             movies
                             &lt;span class="paren1"&gt;(&lt;span class="default"&gt;on &lt;span class="paren2"&gt;(&lt;span class="default"&gt;= movies.id roles.movie_id&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;scope-table &amp;#x27;movies &amp;#x27;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&amp;lt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;col movies year&lt;/span&gt;)&lt;/span&gt; 2005&lt;/span&gt;)&lt;/span&gt; query&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="comment"&gt;;; Results in the following:
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;select &lt;span class="paren2"&gt;(&lt;span class="default"&gt;columns actors.firstname actors.lastname
                 roles.character movies.title&lt;/span&gt;)&lt;/span&gt;
        &lt;span class="paren2"&gt;(&lt;span class="default"&gt;from &lt;span class="paren3"&gt;(&lt;span class="default"&gt;join left
                    &lt;span class="paren4"&gt;(&lt;span class="default"&gt;join left actors
                          &lt;span class="paren5"&gt;(&lt;span class="default"&gt;join inner roles &lt;span class="paren6"&gt;(&lt;span class="default"&gt;as movies m2&lt;/span&gt;)&lt;/span&gt;
                                &lt;span class="paren6"&gt;(&lt;span class="default"&gt;on &lt;span class="paren1"&gt;(&lt;span class="default"&gt;and &lt;span class="paren2"&gt;(&lt;span class="default"&gt;= m2.id roles.movie_id&lt;/span&gt;)&lt;/span&gt;
                                         &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&amp;gt; m2.year 2000&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                          &lt;span class="paren5"&gt;(&lt;span class="default"&gt;on &lt;span class="paren6"&gt;(&lt;span class="default"&gt;= roles.actor_id actors.id&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                    movies
                    &lt;span class="paren4"&gt;(&lt;span class="default"&gt;on &lt;span class="paren5"&gt;(&lt;span class="default"&gt;= movies.id roles.movie_id&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
        &lt;span class="paren2"&gt;(&lt;span class="default"&gt;where &lt;span class="paren3"&gt;(&lt;span class="default"&gt;and &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&amp;lt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;col m2 year&lt;/span&gt;)&lt;/span&gt; 2005&lt;/span&gt;)&lt;/span&gt;
                    &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&amp;lt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;col movies year&lt;/span&gt;)&lt;/span&gt; 2005&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The initial &lt;tt&gt;query&lt;/tt&gt; selects all the films in the database, including all actors with the roles they played in that film.  However, the actors are only included for films that were released after the year 2000.  Earlier films are returned without the actors.&lt;/p&gt;
&lt;p&gt;Now, the magic happens in the call to &lt;tt&gt;scope-table&lt;/tt&gt;, which returns the same query, but with all occurrences of the &lt;tt&gt;movies&lt;/tt&gt; table scoped to include only films released before the year 2005.  Note that this scopes both the main query &lt;i&gt;and&lt;/i&gt; the joined table &lt;tt&gt;m2&lt;/tt&gt; even though it's aliased.&lt;/p&gt;&lt;a href="#its-all-about-the-syntax"&gt;
&lt;h2 id="its-all-about-the-syntax"&gt;It's all about the syntax&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Okay, so it turns out that this idea works beautifully.  Let's look at why I think this DSL was a failure.  One reason is the fact that SQL is a &lt;i&gt;huge&lt;/i&gt; language, especially when you consider all the extensions provided by various implementations.&lt;/p&gt;
&lt;p&gt;You could say &amp;quot;but you don't &lt;i&gt;have&lt;/i&gt; to support the full language&amp;quot;. That's true, but the problem with a language that maps directly to SQL is that users will &lt;i&gt;expect&lt;/i&gt; being able to do all the things they can do in regular SQL.  For example, when &lt;a href="http://www.postgresql.org/docs/current/interactive/queries-with.html" class="external"&gt;Common Table Expressions&lt;/a&gt; were first introduced into PostgreSQL, I started seeing many places in my code bases at work where those would be useful. The same was true for &lt;a href="http://www.postgresql.org/docs/current/interactive/tutorial-window.html" class="external"&gt;Window Functions&lt;/a&gt;. These are both extremely useful extensions, and I'm now making regular use of them.  I wouldn't want to miss them, so any SQL DSL really needs to support them for me to take it seriously.&lt;/p&gt;
&lt;p&gt;The thing both extensions have in common is that they introduce completely new syntax.  That's because there are absolutely &lt;i&gt;no&lt;/i&gt; common building blocks for language constructs; every feature is a set of arbitrarily-placed keywords to help a parser make sense of it (with many optional &amp;quot;noise&amp;quot; keywords to help a human make sense of it). This means each feature has to be taught separately to SSQL, resulting in a large set of rules on how to convert them to SQL.&lt;/p&gt;
&lt;p&gt;The SQL grammar is so complicated that its sheer size has serious performance implications on a parser, &lt;a href="http://rhaas.blogspot.nl/2012/02/my-patches-are-breeding.html" class="external"&gt;as pointed out by this blog post&lt;/a&gt;. Because &lt;tt&gt;EXPLAIN&lt;/tt&gt; is a PostgreSQL extension, they simply decided to change this command's syntax to make it faster to parse. The old syntax is still supported for backwards-compatibility, but this change is a great illustration of how much of a moving target the SQL syntax really is.  Other SQL implementations don't generally move as fast as PostgreSQL in adding features, but as I indicated earlier, I really like these features and use them on a regular basis.&lt;/p&gt;&lt;a href="#database-independence-with-sql-based-syntax"&gt;
&lt;h2 id="database-independence-with-sql-based-syntax"&gt;Database independence with SQL-based syntax?&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Another complication is supporting multiple databases.  SSQL supports ANSI SQL as a baseline, with optional extensions that are available if the back-end supports it.  The nice thing is that this provides a degree of database independence.  All back-ends can automatically quote strings and table names correctly depending on the database, making &lt;a href="http://owasp.com/index.php/SQL_Injection" class="external"&gt;SQL injection bugs&lt;/a&gt; effectively &lt;i&gt;impossible&lt;/i&gt;.  For example,&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&amp;#x27;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;select &lt;span class="paren2"&gt;(&lt;span class="default"&gt;columns &lt;span class="paren3"&gt;(&lt;span class="default"&gt;col actors firstname lastname birth-date&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren2"&gt;(&lt;span class="default"&gt;from actors&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren2"&gt;(&lt;span class="default"&gt;where &lt;span class="paren3"&gt;(&lt;span class="default"&gt;= actors.lastname &lt;span class="string"&gt;&amp;quot;O&amp;#x27;Neill&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;gets output as the following in PostgreSQL and SQLite:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; SELECT actors.firstname, actors.lastname, actors.&amp;quot;birth-date&amp;quot;
 FROM actors
 WHERE actors.lastname = 'O''Neill';&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The MySQL back-end outputs the following:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; SELECT actors.firstname, actors.lastname, actors.`birth-date`
 FROM actors
 WHERE actors.lastname = 'O\'Neill';&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;These differences are relatively small and don't affect the syntax of the S-expression version.  However, there are other examples that do. For example, MySQL's &lt;tt&gt;INSERT&lt;/tt&gt; statement allows syntax which mirrors the &lt;tt&gt;UPDATE&lt;/tt&gt; statement, using &lt;tt&gt;SET&lt;/tt&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; INSERT INTO movies SET title = 'Alien', year = 1979;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;whereas PostgreSQL only allows the standard syntax (which MySQL &lt;i&gt;also&lt;/i&gt; supports):&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; INSERT INTO movies (title, year) VALUES ('Donnie Darko', 2001);&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The question then becomes whether the (unnecessary) syntax with &lt;tt&gt;SET&lt;/tt&gt; should be allowed, and, if so, whether this should be emulated in PostgreSQL by rewriting it to the standard syntax.  There are tens of such silly examples (&lt;tt&gt;CONCAT&lt;/tt&gt; versus &lt;tt&gt;||&lt;/tt&gt; versus logical &lt;tt&gt;OR&lt;/tt&gt;, case insensitive &lt;tt&gt;LIKE&lt;/tt&gt; versus &lt;tt&gt;ILIKE&lt;/tt&gt;, etc), but there are a lot of more fundamental differences, too.  Finally, using ANSI as a baseline is nice, but many of ANSI's features aren't widely implemented.  Common Table Expressions are a good example; they're standardized, but neither MySQL nor SQLite support them, and Postgres only started supporting them very recently.  Oh, and fuck proprietary RDBMSes; Oracle long ignored ANSI and invented more nonstandard extensions than MySQL ever did, and as a result, &lt;a href="http://it.toolbox.com/blogs/oracle-experience/a-case-for-ansi-sql-15647" class="external"&gt;their users&lt;/a&gt; are as &lt;a href="http://allthingsoracle.com/ansi-sql/" class="external"&gt;clueless&lt;/a&gt; about ANSI SQL as the average MySQL user.  Finally, there are many ANSI features that none of these databases support.  This means you have to implement a feature in ANSI, then override it to produce an error message saying it's unsupported in this dialect for all implementations that &lt;i&gt;don't&lt;/i&gt; support it.  An alternative approach is to implement no base but make everything completely implementation-specific.  However, this results in a bigger risk of producing DSL inconsistencies between dialects.&lt;/p&gt;&lt;a href="#a-better-approach"&gt;
&lt;h2 id="a-better-approach"&gt;A better approach&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Recently, the &lt;a href="http://en.wikipedia.org/wiki/Relational_algebra" class="external"&gt;relational algebra&lt;/a&gt; has been gaining some more interest.  For example, there's &lt;a href="http://blambeau.github.com/alf/overview/index.html" class="external"&gt;Alf&lt;/a&gt; for Ruby and the UNIX shell, and of course &lt;a href="https://github.com/rails/arel" class="external"&gt;Arel&lt;/a&gt;, which I mentioned earlier.&lt;/p&gt;
&lt;p&gt;I think this is a better approach; relational algebra has just a handful of concepts and there's no syntax associated with it, so you can invent your own syntax to best fit your DSL.  It also prevents you from getting distracted by the differences in various SQL implementations.  You can see this with Alf already; it has total abstraction over the DBMS.  It can use flat files or SQL, or any other back-end you'd like, as long as it fits the relational model (to be fair, so can PostgreSQL with SQL/MED &lt;a href="http://wiki.postgresql.org/wiki/Foreign_data_wrappers" class="external"&gt;foreign data wrappers&lt;/a&gt;). The flip side of such a high level of abstraction is that it will be harder to make use of any killer features offered by your RDBMS; you get the lowest common denominator in features.&lt;/p&gt;
&lt;p&gt;Optimizing queries also becomes hard.  You can no longer hand-optimize them when writing them, and you'd probably end up with an optimizer in your library.  This is pretty insane, since there's also an SQL optimizer and query planner inside your RDBMS, so you're doing twice the work, and there's twice the opportunity for getting it wrong.&lt;/p&gt;
&lt;p&gt;Despite these disadvantages, the &amp;quot;relational algebra DSL&amp;quot; approach is more viable than the &amp;quot;SQL DSL&amp;quot; approach.  ClojureQL also initially took the approach of providing a DSL closely modeled on SQL, but later &lt;a href="http://www.bestinclass.dk/index.clj/2010/11/clojureql--revolutions.html" class="external"&gt;completely revised the DSL&lt;/a&gt; to be more abstract and closer to relational algebra than to SQL.&lt;/p&gt;
&lt;p&gt;I think it's interesting to see what other SQL-like DSL projects will do.  For example, Clojure also has &lt;a href="https://web.archive.org/web/20190223025406/http://www.sqlkorma.com/" class="external"&gt;Korma&lt;/a&gt;, which is rather close to SQL and looks like it can currently only perform a limited subset of all possible queries.  I wonder what they'll do when users start clamoring for richer back-end support? Racket used to have SchemeQL, but that project seems to have vanished from the web.  The website of its parent project, &lt;a href="http://schematics.sourceforge.net" class="external"&gt;Schematics&lt;/a&gt;, doesn't mention it at all anymore.  The same seems to have happened to a Common Lisp interface called &lt;a href="http://www.cliki.net/cl-rdbms" class="external"&gt;CL-RDBMS&lt;/a&gt; (at least the &amp;quot;homepage&amp;quot; link currently points to a broken web site).&lt;/p&gt;
&lt;p&gt;There's a popular library for Common Lisp called &lt;a href="http://clsql.kpe.io/" class="external"&gt;CLSQL&lt;/a&gt;. It looks like an &lt;i&gt;enormous&lt;/i&gt; amount of engineering went into it.  If that's required to get a useful SQL DSL, it might not be worth it unless the advantages outweigh the effort required.  Note that even after 10 years of development, CLSQL still has &lt;a href="http://lists.kpe.io/pipermail/clsql/2012-July/002077.html" class="external"&gt;no outer join support&lt;/a&gt;. I think that's indicative of how hard it is to &lt;i&gt;properly&lt;/i&gt; support SQL from a DSL.&lt;/p&gt;&lt;a href="#wrap-up"&gt;
&lt;h2 id="wrap-up"&gt;Wrap-up&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;The lessons I learned from the SSQL experiment are in retrospect rather simple, and seem to echo earlier blog posts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The language you're targeting should be small and have few core concepts.&lt;/li&gt;
&lt;li&gt;The relevant standards should be fully implemented in all back-ends you want to support.&lt;/li&gt;
&lt;li&gt;Back-ends shouldn't have any arbitrary extensions that you're expected to support.&lt;/li&gt;
&lt;li&gt;Look for an underlying theory; this may be a better abstraction than the target language.&lt;/li&gt;
&lt;li&gt;Try to find examples of similar libraries.  Did others try, and fail or give up?  If so, why?  How complex are existing implementations?  Are they complete?&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;This post will be the last post in this series, at least for a while. There aren't that many other interesting DSLs with which I'm familiar, and I've exhausted the list of novel design concepts that I'm able to distill from existing DSLs.&lt;/p&gt;</content>
    <id>tag:more-magic,2012-08-20:/posts/lispy-dsl-ssql.html</id>
    <published>2012-08-20T19:19:40Z</published>
    <title type="text">Designing Lispy DSLs, part 4: SSQL</title>
    <updated>2012-08-20T19:19:40Z</updated>
    <link href="https://www.more-magic.net/posts/lispy-dsl-ssql.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;Today I'd like to discuss Scheme Regular Expressions (SRE). Originally introduced in a library for the &lt;a href="http://www.scsh.net/docu/html/man-Z-H-7.html" class="external"&gt;Scheme Shell&lt;/a&gt;, this DSL has recently been gaining some popularity due to the release of &lt;a href="http://synthcode.com/scheme/irregex" class="external"&gt;Irregex&lt;/a&gt;, a &lt;i&gt;pure R5RS Scheme&lt;/i&gt; regex engine with SRE as its native syntax.  Irregex has been integrated as the core regex system in &lt;a href="http://wiki.call-cc.org/man/4/Unit%20irregex#unit-irregex" class="external"&gt;Chicken Scheme&lt;/a&gt; and &lt;a href="http://www.jazzscheme.org/reference.htm#irregex" class="external"&gt;Jazz Scheme&lt;/a&gt;, and you can easily use it from any other Scheme due to its portability.&lt;/p&gt;
&lt;p&gt;Back in 1998, the author of the first SRE implementation (Olin Shivers, one of the &lt;a href="http://www.scsh.net/docu/html/man.html" class="external"&gt;funniest Schemers&lt;/a&gt; around) posted &lt;a href="http://www.scsh.net/docu/post/sre.html" class="external"&gt;an announcement&lt;/a&gt; to several newsgroups about this new syntax.  It's well worth a read; especially the preamble about 100% and 80% solutions is a very inspiring &lt;i&gt;call to arms&lt;/i&gt; which provides a good insight into the Scheme way of thinking.  By the way, if you liked this, you'll also want to read the classic essay &amp;quot;&lt;a href="http://dreamsongs.com/WIB.html" class="external"&gt;Worse Is Better&lt;/a&gt;&amp;quot;, if you haven't already.  The bit about &amp;quot;The Right Way&amp;quot; is especially relevant. Consider yourself warned, Schemer!&lt;/p&gt;&lt;a href="#figuring-out-the-rules"&gt;
&lt;h2 id="figuring-out-the-rules"&gt;Figuring out the rules&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;The &amp;quot;Discussion and design notes&amp;quot; section from the announcement is particularly interesting as it discusses the DSL from a point of view similar to this series of blog posts.  It's also the largest section, so we'll just touch upon the important points here.  The first thing that really jumps out is the fact that the author has taken a look at &lt;i&gt;many&lt;/i&gt; different regex packages for various languages, and even asked Tom Lord and &lt;a href="http://en.wikipedia.org/wiki/Henry_Spencer" class="external"&gt;Henry Spencer&lt;/a&gt; (both wrote their own regex engines) about obscure details.  Doing this kind of in-depth research is a great way to get started when designing a DSL since it provides you with a nicely broad perspective on the various viewpoints of others who went before you.  This will reduce your &amp;quot;blindness to complexity&amp;quot;.  Initially every target language seems simple but there are always pitfalls which, if overlooked, would result in a DSL that's hard to extend or doesn't provide all the features of the target language which a user would need.  By looking at other implementations you see how they deal with the more complex nooks and crannies of the target language.&lt;/p&gt;
&lt;p&gt;The other main point is that he drew a very clear line in the sand of what features would go into SRE and which wouldn't.  The SRE syntax doesn't support any &amp;quot;extended regex&amp;quot; features which would force a particular implementation strategy.  This makes the SRE syntax independent of the underlying regex engine, which allows for greater portability and generality, but more importantly, it &lt;i&gt;leaves open the possibility of efficient implementations&lt;/i&gt;.  This was misunderstood by many people; he had to &lt;a href="http://www.scsh.net/docu/post/sreadt.html" class="external"&gt;educate Richard Stallman&lt;/a&gt; about why supporting back references in the general SRE syntax is a bad idea:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt; My feeling about back references is as follows. Regexps are based on a deep
 theory -- regular sets and DFA's -- that has tremendous implications about
 the operations you can perform on them and the ways you can implement them.
 Back-references completely shatter this framework. They rule out certain
 extremely efficient implementations. They rule out certain operations. They
 have nothing to do with the idea of a &amp;quot;regular expression.&amp;quot; They are not one
 with the deep structure of the system.&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Repeat that in your mind: &lt;i&gt;They are not one with the deep structure of the system&lt;/i&gt;.  DSL design notes don't get any more philosophical than that!  This points right to the core design principle of SRE (and regexes in general).  If you are designing a DSL, you can consider yourself very lucky when you find a guiding principle which is that strong.  You should let it inform all your design choices because it will help you achieve a good, cohesive design.  This also makes it easier to defend your choices when users start complaining about missing features...&lt;/p&gt;&lt;a href="#representational-issues"&gt;
&lt;h2 id="representational-issues"&gt;Representational issues&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;After my &lt;a href="/posts/lispy-dsl-scss.html" class="internal"&gt;SCSS post&lt;/a&gt;, I was asked why you'd want to represent CSS using &lt;i&gt;first-class&lt;/i&gt; values.  I think the &lt;a href="/posts/lispy-dsl-sxml.html" class="internal"&gt;SXML&lt;/a&gt; DSL example illustrates how powerful a first-class representation &lt;i&gt;can&lt;/i&gt; be, but I must admit, I don't see many valid use-cases for &amp;quot;first-classing&amp;quot; a CSS DSL.&lt;/p&gt;
&lt;p&gt;However, one important lesson in programming is that you never know what clever things people are going to do with your code; clever things you only &lt;i&gt;wish&lt;/i&gt; you thought about.  You should see first-class values as an &lt;i&gt;enabler&lt;/i&gt; for other people to take your DSL's usefulness to new heights.  The &amp;quot;&lt;a href="http://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-3.html" class="external"&gt;Prime Clingerism&lt;/a&gt;&amp;quot; applies to DSLs as well; without a first-class representation, additional features will appear necessary to perform useful operations.&lt;/p&gt;
&lt;p&gt;One interesting aspect of the design of the original SRE library for SCSH is how it deals with first-class regexps.  It contains a large set of procedures to manipulate the underlying regular expression &lt;a href="http://www.scsh.net/docu/html/man-Z-H-7.html#node_sec_6.5" class="external"&gt;ADT&lt;/a&gt; (abstract data type).  Olin believed a separate ADT was required for easy manipulation of regex objects, and it would also allow extension of the supported operator set.  Directly operating on the SRE expressions would be harder for programmatic extensions.  This distinction allows for a &lt;i&gt;baroque&lt;/i&gt; but user-friendly SRE syntax in which it is possible to write one thing in many different ways, while also offering ease of manipulation from user code.&lt;/p&gt;
&lt;p&gt;Olin is quick to point out that this does cause massive complexity in the code (a point also &lt;a href="http://www.scsh.net/docu/post/sreadt.html" class="external"&gt;raised&lt;/a&gt; by Richard Stallman), but says the work is done now and anyone is free to take his code and re-use it (this fits the &amp;quot;100% solution&amp;quot; ideology mentioned at the beginning).  This ADT approach is comparable to how Lisp/Scheme compilers internally rewrite the full language to a simpler to manipulate &amp;quot;core language&amp;quot;, so it isn't completely unique to SRE.&lt;/p&gt;
&lt;p&gt;At first glance, this seems a little hard to defend, especially the fact that there's also a seemingly unnecessary &lt;tt&gt;rx&lt;/tt&gt; macro in his design, while Irregex gets by fine without these.  I've asked &lt;a href="http://synthcode.com/" class="external"&gt;Alex Shinn&lt;/a&gt;, the author of Irregex, about this, and he mentioned that the macro and the ADT were needed in SCSH because it depended on an underlying POSIX regex engine rather than implementing it natively in Scheme.  SCSH first reads SREs at compile-time and the macro tries to compile down to the ADT as much as possible.  Then, at run-time, this ADT is converted to a POSIX regex string which is compiled by the underlying C regex engine.&lt;/p&gt;
&lt;p&gt;Because Irregex &lt;i&gt;is&lt;/i&gt; written natively in Scheme, this extra step is not necessary and Alex decided to get rid of these distractions and implement only the SRE syntax, without the &lt;tt&gt;rx&lt;/tt&gt; macro and ADT.  The result is a very compact implementation, having about the same size as the SCSH package, but including a full matching engine!  As far as I know there isn't any widely-used extension for SCSH which makes use of the ADT interface, and the SRE syntax hasn't been extended as much as Olin foresaw might happen.  For these reasons, the choice to drop all that complexity seems like a wise one.  However, only time will tell whether that's really the case.&lt;/p&gt;&lt;a href="#wrapping-up"&gt;
&lt;h2 id="wrapping-up"&gt;Wrapping up&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Let's see what we have learned from the design of SRE:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Do your research! Inspect as many libraries and DSLs as possible to gain a broad perspective and avoid &amp;quot;blindness to complexity&amp;quot;.  If in doubt, ask a domain guru.&lt;/li&gt;
&lt;li&gt;Relentlessly strip all features that preclude efficient implementation strategies.  When users request them back, &lt;i&gt;resist&lt;/i&gt;!&lt;/li&gt;
&lt;li&gt;Design for extensibility and programmability; strive to support a first-class representation.&lt;/li&gt;
&lt;li&gt;When things have settled down, re-evaluate the design and drop unnecessary features.&lt;/li&gt;
&lt;li&gt;You don't always need nitty-gritty details from code examples to analyse a DSL :)&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;I admit, some of these rules are not for the faint of heart, but they make for a very strong and coherent DSL which might see wider adoption than just your initial implementation.&lt;/p&gt;</content>
    <id>tag:more-magic,2012-08-14:/posts/lispy-dsl-sre.html</id>
    <published>2012-08-14T17:52:14Z</published>
    <title type="text">Designing Lispy DSLs, part 3: SRE</title>
    <updated>2012-08-14T17:52:14Z</updated>
    <link href="https://www.more-magic.net/posts/lispy-dsl-sre.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;After &lt;a href="/posts/lispy-dsl-scss.html" class="internal"&gt;last time's example of SCSS&lt;/a&gt;, I'd like to take a look at &lt;a href="http://ssax.sourceforge.net/" class="external"&gt;SXML&lt;/a&gt;, another Lispy DSL I'm using in this blog.  It's more successful and more widely-used than SCSS and even has &lt;a href="http://okmij.org/ftp/Scheme/SXML.html" class="external"&gt;an official specification&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;The observation that &lt;a href="http://www.w3.org/TR/REC-xml/" class="external"&gt;XML&lt;/a&gt; is really an obnoxiously verbose Lisp without parens is common, but the details are (of course) hairier than that.  Let's look at an XHTML example:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight xhtml-language"&gt;&amp;lt;&lt;span class="variable"&gt;div&lt;/span&gt;&amp;gt;
  &amp;lt;&lt;span class="variable"&gt;span&lt;/span&gt;&amp;gt;Hello, &amp;lt;&lt;span class="variable"&gt;strong&lt;/span&gt;&amp;gt;dear&amp;lt;/&lt;span class="variable"&gt;strong&lt;/span&gt;&amp;gt; friends.&amp;lt;/&lt;span class="variable"&gt;span&lt;/span&gt;&amp;gt;
  &amp;lt;&lt;span class="variable"&gt;span&lt;/span&gt;&amp;gt;This is a &lt;span class="character"&gt;&amp;amp;lt;&lt;/span&gt;simple&lt;span class="character"&gt;&amp;amp;gt;&lt;/span&gt; example.&amp;lt;/&lt;span class="variable"&gt;span&lt;/span&gt;&amp;gt;
&amp;lt;/&lt;span class="variable"&gt;div&lt;/span&gt;&amp;gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Converting this HTML fragment to an S-expression is straightforward:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&amp;#x27;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;div
   &lt;span class="paren2"&gt;(&lt;span class="default"&gt;span &lt;span class="string"&gt;&amp;quot;Hello, &amp;quot;&lt;/span&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;strong &lt;span class="string"&gt;&amp;quot;dear&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="string"&gt;&amp;quot; friends.&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
   &lt;span class="paren2"&gt;(&lt;span class="default"&gt;span &lt;span class="string"&gt;&amp;quot;This is a &amp;lt;simple&amp;gt; example.&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;It's a bit more cumbersome to type because you have to break up the strings for the &amp;quot;&lt;tt&gt;strong&lt;/tt&gt;&amp;quot; element, but aside from that it's simpler, shorter, and less error-prone; &amp;quot;special&amp;quot; characters can be written as-is since they are automatically escaped when the XML document is written.  Especially when dealing with large templates and generated content it can be a big time-saver to represent XML as S-expressions; doubly so if you're using &lt;a href="http://www.emacswiki.org/emacs/ParEdit" class="external"&gt;paredit&lt;/a&gt;.  Plus, Scheme is your templating language, and Lisps are rather good at processing lists :)&lt;/p&gt;
&lt;p&gt;You might be wondering about XML attributes; S-expressions don't have anything that maps naturally to these.  Some XML-in-Lisp variants use keywords for attributes, others use alternating symbols and strings to indicate attributes.  SXML takes the more interesting approach that attributes in XML were a &lt;i&gt;mistake&lt;/i&gt;; there should only be &lt;i&gt;elements&lt;/i&gt;.  To compensate, SXML uses a tag name that can't exist in XML (the &amp;quot;@&amp;quot;-sign) and it has the convention that this element can appear as the first child of any element.  Child element names represent attribute names, their text contents represent values.  The &amp;quot;@&amp;quot;-sign is particularly well-chosen because W3C also uses it elsewhere to indicate attributes (e.g. in XPath and XSLT).&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight xhtml-language"&gt;&amp;lt;&lt;span class="variable"&gt;div&lt;/span&gt; &lt;span class="variable"&gt;id&lt;/span&gt;=&lt;span class="string"&gt;&amp;quot;welcome&amp;quot;&lt;/span&gt; &lt;span class="variable"&gt;class&lt;/span&gt;=&lt;span class="string"&gt;&amp;quot;section&amp;quot;&lt;/span&gt;&amp;gt;
  &amp;lt;&lt;span class="variable"&gt;span&lt;/span&gt;&amp;gt;Hello, &amp;lt;&lt;span class="variable"&gt;strong&lt;/span&gt; &lt;span class="variable"&gt;class&lt;/span&gt;=&lt;span class="string"&gt;&amp;quot;affectionately&amp;quot;&lt;/span&gt;&amp;gt;dear&amp;lt;/&lt;span class="variable"&gt;strong&lt;/span&gt;&amp;gt;friends.&amp;lt;/&lt;span class="variable"&gt;span&lt;/span&gt;&amp;gt;
  &amp;lt;&lt;span class="variable"&gt;span&lt;/span&gt;&amp;gt;This is a &lt;span class="character"&gt;&amp;amp;lt;&lt;/span&gt;simple&lt;span class="character"&gt;&amp;amp;gt;&lt;/span&gt; example.&amp;lt;/&lt;span class="variable"&gt;span&lt;/span&gt;&amp;gt;
&amp;lt;/&lt;span class="variable"&gt;div&lt;/span&gt;&amp;gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;becomes:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&amp;#x27;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;div &lt;span class="paren2"&gt;(&lt;span class="default"&gt;@ &lt;span class="paren3"&gt;(&lt;span class="default"&gt;id &lt;span class="string"&gt;&amp;quot;welcome&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;class &lt;span class="string"&gt;&amp;quot;section&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;span &lt;span class="string"&gt;&amp;quot;Hello, &amp;quot;&lt;/span&gt; &lt;span class="paren3"&gt;(&lt;span class="default"&gt;strong &lt;span class="paren4"&gt;(&lt;span class="default"&gt;@ &lt;span class="paren5"&gt;(&lt;span class="default"&gt;class &lt;span class="string"&gt;&amp;quot;affectionately&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;dear&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="string"&gt;&amp;quot; friends.&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;span &lt;span class="string"&gt;&amp;quot;This is a &amp;lt;simple&amp;gt; example.&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Let's look at what makes SXML such a good DSL.  First, XML has a hierarchical structure, which maps well to S-expressions.  It is built up out of only a handful of atoms: it has start tags with attributes, end tags, entities, and textual content in between.  In SXML, tag names are mapped to symbols, which can represent &lt;i&gt;any&lt;/i&gt; string, so this naturally extends to all possible XML tag names.&lt;/p&gt;
&lt;p&gt;When building websites, the fact that regular HTML is less strict than XML is irrelevant; you don't &lt;i&gt;need&lt;/i&gt; features like, say, &lt;i&gt;omitting an end tag&lt;/i&gt;.  In fact, end tags don't even exist in SXML; it models the underlying concept of &lt;i&gt;elements&lt;/i&gt; rather than &lt;i&gt;tags&lt;/i&gt;; it simply treats tags as artifacts of the serialized textual representation of an element.  S-expressions can be seen as an &lt;i&gt;alternative&lt;/i&gt; serialized textual representation of the same document described by the &amp;quot;angular brackets and tags&amp;quot; notation.&lt;/p&gt;
&lt;p&gt;This is another important aspect of good DSLs; they tend to ignore surface syntax.  Instead, they map the underlying tree-like structure to S-expressions.  SXML uses elements instead of letting itself get distracted by tags, and it generalizes attributes to fit the tree structure.  By representing the structure in S-expressions, you know what parts need to be &amp;quot;escaped&amp;quot; in order to preserve this structure. When writing SXML to XML, all string elements in an SXML document get their angular brackets &lt;tt&gt;&amp;lt;&lt;/tt&gt; and &lt;tt&gt;&amp;gt;&lt;/tt&gt; converted to &lt;tt&gt;&amp;amp;lt;&lt;/tt&gt; and &lt;tt&gt;&amp;amp;gt;&lt;/tt&gt;.  The &lt;i&gt;only&lt;/i&gt; angular brackets ending up in the output are those that result from serialization of elements to start/end tags. When reading XML, &lt;i&gt;all&lt;/i&gt; entities are automatically converted to the characters they represent, so in Scheme you get to work directly with the text contents at the conceptual level.  &lt;tt&gt;CDATA&lt;/tt&gt; sections are also eliminated; they are simply represented by their string value.&lt;/p&gt;&lt;a href="#some-complications"&gt;
&lt;h2 id="some-complications"&gt;Some complications&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;XML isn't as simple as you'd think at first glance.  Remember the same observation about CSS?  This is a common theme with web technology. Don't even get me started about HTTP!  In the &lt;a href="http://okmij.org/ftp/Scheme/SSAX-v4.txt" class="external"&gt;words&lt;/a&gt; of Oleg Kiselyov, author of the SXML specification and many tools in the &lt;a href="http://ssax.sf.net" class="external"&gt;SSAX project&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;There exists a myth that parsing of XML is easy. An article &amp;quot;Parsing XML&amp;quot;
in the January 2000 issue of Dr.Dobb's Journal states the ease of parsing
as an alleged fact. The author of that article must have overlooked that
there is more to XML than the grammar presented in the XML Recommendation.
There are attribute normalization rules, well-formedness constraints, let
alone validation constraints. XML Namespaces add another layer of complexity.&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;You can almost &lt;i&gt;hear&lt;/i&gt; his frustration...  Here's an example to illustrate some things that so far we have glossed over.  This isn't a fragment, but a &lt;i&gt;full&lt;/i&gt; XML document (with thanks to &lt;a href="http://3e8.org/blog/2010/08/01/default-namespaces-in-sxml/" class="external"&gt;Jim Ursetto&lt;/a&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight xml-language"&gt;&lt;span class="keyword"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;/span&gt;
&amp;lt;&lt;span class="variable"&gt;feed&lt;/span&gt; &lt;span class="variable"&gt;xmlns&lt;/span&gt;=&lt;span class="string"&gt;&amp;quot;http://www.w3.org/2005/Atom&amp;quot;&lt;/span&gt;&amp;gt;
  &amp;lt;&lt;span class="variable"&gt;entry&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span class="variable"&gt;content&lt;/span&gt; &lt;span class="variable"&gt;type&lt;/span&gt;=&lt;span class="string"&gt;&amp;quot;xhtml&amp;quot;&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span class="variable"&gt;div&lt;/span&gt; &lt;span class="variable"&gt;xmlns&lt;/span&gt;=&lt;span class="string"&gt;&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;/span&gt;&amp;gt;
        &amp;lt;&lt;span class="variable"&gt;p&lt;/span&gt;&amp;gt;I&amp;#x27;m invincible!&amp;lt;/&lt;span class="variable"&gt;p&lt;/span&gt;&amp;gt;
      &amp;lt;/&lt;span class="variable"&gt;div&lt;/span&gt;&amp;gt;
    &amp;lt;/&lt;span class="variable"&gt;content&lt;/span&gt;&amp;gt;
  &amp;lt;/&lt;span class="variable"&gt;entry&lt;/span&gt;&amp;gt;
&amp;lt;/&lt;span class="variable"&gt;feed&lt;/span&gt;&amp;gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;There are two new things to notice: The document starts with a &amp;quot;special&amp;quot; syntax to indicate that we're using XML version 1.0. These so-called &lt;a href="http://www.w3.org/TR/REC-xml/#sec-pi" class="external"&gt;processing instructions&lt;/a&gt; provide a generic way of passing (meta-)information to the application, outside the XML document itself.  The second new thing is that the &lt;a href="http://tools.ietf.org/html/rfc4287" class="external"&gt;Atom&lt;/a&gt; feed in this example holds an XHTML document fragment as a &lt;i&gt;sub-document&lt;/i&gt;.  It uses a &lt;a href="http://www.w3.org/TR/2009/REC-xml-names-20091208/" class="external"&gt;namespace&lt;/a&gt; declaration to indicate that the &lt;tt&gt;div&lt;/tt&gt; and &lt;tt&gt;p&lt;/tt&gt; tags are taken from a different XML schema than the main document.&lt;/p&gt;
&lt;p&gt;Let's see how SXML deals with these new concepts.  This document can be represented in several ways, but the following is arguably the simplest:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;span class="special"&gt;*TOP*&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;@ &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="special"&gt;*NAMESPACES*&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;atom &lt;span class="string"&gt;&amp;quot;http://www.w3.org/2005/Atom&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
                        &lt;span class="paren4"&gt;(&lt;span class="default"&gt;xhtml &lt;span class="string"&gt;&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="special"&gt;*PI*&lt;/span&gt; xml &lt;span class="string"&gt;&amp;quot;version=&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;1.0&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;atom:feed
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;atom:entry
      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;atom:content &lt;span class="paren5"&gt;(&lt;span class="default"&gt;@ &lt;span class="paren6"&gt;(&lt;span class="default"&gt;type &lt;span class="string"&gt;&amp;quot;xhtml&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
        &lt;span class="paren5"&gt;(&lt;span class="default"&gt;xhtml:div &lt;span class="paren6"&gt;(&lt;span class="default"&gt;xhtml:p &lt;span class="string"&gt;&amp;quot;I&amp;#x27;m invincible!&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;If you look carefully at the original XML document, you'll see that while &lt;tt&gt;feed&lt;/tt&gt; is the document's root node, it still has a sibling: the processing instruction!  There's a &amp;quot;virtual&amp;quot; root element that holds these two, which XML calls the &amp;quot;&lt;a href="http://www.w3.org/TR/REC-xml/#dt-docent" class="external"&gt;document entity&lt;/a&gt;&amp;quot;.  SXML generalizes this to an element called &lt;tt&gt;*TOP*&lt;/tt&gt; (for &amp;quot;top-level&amp;quot;). The &lt;tt&gt;*NAMESPACES*&lt;/tt&gt; element (an &amp;quot;attribute&amp;quot; of &lt;tt&gt;*TOP*&lt;/tt&gt;) stores an association list of element name prefixes used to indicate a namespace.  The &lt;tt&gt;*PI*&lt;/tt&gt; element is SXML's way of representing the processing instruction (its &lt;tt&gt;version&lt;/tt&gt; &amp;quot;attribute&amp;quot; isn't parsed because it isn't a true attribute in terms of XML; it just &lt;i&gt;looks&lt;/i&gt; like one.  Don't ask...).&lt;/p&gt;
&lt;p&gt;All three &lt;i&gt;pseudo-elements&lt;/i&gt; are represented by symbols that are invalid XML tag names due to the asterisk.  Just like the &lt;tt&gt;@&lt;/tt&gt; for attributes, this ensures that they can't possibly clash with any tag name that might occur in a particular document type or future versions of XML.&lt;/p&gt;
&lt;p&gt;One disadvantage of encoding namespaces as part of the tag name is that you can't see what namespace a particular element belongs to without first converting the symbol to a string, and then splitting it at the colon.  This means namespaces aren't really &lt;i&gt;first class&lt;/i&gt;. Most likely this is the case because namespaces were added at a later stage when most of the SXML syntax was already set in stone, and modifying it in some other way to support namespaces would be too invasive.&lt;/p&gt;&lt;a href="#tool-set"&gt;
&lt;h2 id="tool-set"&gt;Tool set&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;You only realize the absolute brilliance of SXML when you look at its tool set.  The XML ecosystem is an entire &lt;i&gt;zoo&lt;/i&gt; of mini-languages. Most of these languages (for example &lt;a href="http://www.w3.org/TR/xpath/" class="external"&gt;XPath&lt;/a&gt;, &lt;a href="http://www.w3.org/TR/xlink11/" class="external"&gt;XLink&lt;/a&gt;, &lt;a href="http://www.w3.org/TR/xslt" class="external"&gt;XSLT&lt;/a&gt;) have some kind of corresponding DSL in the SSAX project.  This makes it a complete toolbox for anyone working with XML.  Sure, the &lt;a href="http://okmij.org/ftp/Scheme/xml.html" class="external"&gt;documentation&lt;/a&gt; is incoherent and a little on the &amp;quot;academic&amp;quot; side, and the &lt;a href="http://ssax.sourceforge.net/" class="external"&gt;SSAX SourceForge project&lt;/a&gt; is a random collection of loosely-related tools that aren't exactly idiomatic Scheme (if there even is such a thing), but go ahead and compare it with tools in other languages.&lt;/p&gt;
&lt;p&gt;Most &amp;quot;stock&amp;quot; XML libraries are awkward contraptions. &lt;a href="http://search.cpan.org/~shlomif/XML-LibXML-2.0003/lib/XML/LibXML/Element.pod" class="external"&gt;Usually&lt;/a&gt; &lt;a href="http://www.phpro.org/tutorials/Introduction-To-SimpleXML-With-PHP.html#7" class="external"&gt;they&lt;/a&gt; &lt;a href="https://developer.mozilla.org/en/Traversing_an_HTML_table_with_Javascript_and_DOM_Interfaces" class="external"&gt;expose&lt;/a&gt; &lt;a href="http://www.germane-software.com/software/XML/rexml/doc/classes/REXML/Element.html" class="external"&gt;highly&lt;/a&gt; &lt;a href="http://www.cafeconleche.org/books/xmljava/chapters/ch13s02.html#IndentedFibonacci.java" class="external"&gt;verbose&lt;/a&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/system.xml.xmltextwriter" class="external"&gt;object-oriented&lt;/a&gt; APIs based on the &lt;a href="http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html" class="external"&gt;W3C DOM specification&lt;/a&gt;, where constructing even a small tree takes several lines of code. It's &lt;i&gt;so&lt;/i&gt; awkward that many programmers will tend to prefer generating the XML manually, by writing out strings.&lt;/p&gt;
&lt;p&gt;Dynamic languages tend to do better.  First, in Perl, there's &lt;a href="http://search.cpan.org/dist/XML-Simple/lib/XML/Simple.pm" class="external"&gt;XML::Simple&lt;/a&gt;. This is a little awkward due to Perl's hash and array syntax, but other than that it is a lot like SXML.  However, this library is &lt;i&gt;deprecated&lt;/i&gt; in favor of one of those awkward OO libraries, &lt;a href="http://search.cpan.org/perldoc?XML%3A%3ALibXML" class="external"&gt;XML::LibXML&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://nokogiri.org/Nokogiri/XML/Builder.html" class="external"&gt;Ruby&lt;/a&gt; and &lt;a href="http://lxml.de/tutorial.html#the-e-factory" class="external"&gt;Python&lt;/a&gt; have convenient &amp;quot;builder&amp;quot; objects which can really speed up generation of XML, but as the name says, these are for &lt;i&gt;building&lt;/i&gt;.  The format in which you build isn't directly the first-class representation, which makes the API slightly disparate.  For both languages, these are not the default libraries either, which makes them less likely to be used by people who want to minimize dependencies.&lt;/p&gt;
&lt;p&gt;Finally, even though it's a very static language, Haskell has a pretty good &lt;a href="http://www.haskell.org/haskellwiki/HXT#Document_construction_examples" class="external"&gt;builder-like&lt;/a&gt; library too, which seems quite popular.  If you ever need to generate XML (or &amp;quot;just&amp;quot; HTML) with one of these languages, do yourself a favor and use one of these libraries.&lt;/p&gt;
&lt;p&gt;But back to SXML; let's see how you'd read in a document, manipulate it, and write it back out again.  For a change, the code presented is a &lt;i&gt;complete&lt;/i&gt; (&lt;a href="http://www.call-with-current-continuation.org" class="external"&gt;Chicken&lt;/a&gt;) Scheme program.  This will read one of the first XML documents in this post, change it, and send it to standard output.&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="comment"&gt;;; First, run the following from the shell to ensure this program will work:
&lt;/span&gt;&lt;span class="comment"&gt;;; $ chicken-install ssax sxml-modifications sxml-serializer
&lt;/span&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;use ssax sxml-modifications sxml-serializer&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; doc &lt;span class="paren2"&gt;(&lt;span class="default"&gt;ssax:xml-&amp;gt;sxml &lt;span class="paren3"&gt;(&lt;span class="default"&gt;current-input-port&lt;/span&gt;)&lt;/span&gt; &amp;#x27;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;define&lt;/span&gt;&lt;/i&gt; change
  &lt;span class="paren2"&gt;(&lt;span class="default"&gt;sxml-modify
    `&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;div/@id&amp;quot;&lt;/span&gt; replace &lt;span class="paren4"&gt;(&lt;span class="default"&gt;id &lt;span class="string"&gt;&amp;quot;good-bye&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    `&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;../span[1]/text()[1]&amp;quot;&lt;/span&gt; replace &lt;span class="string"&gt;&amp;quot;Goodbye, &amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    `&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;../following::*&amp;quot;&lt;/span&gt; replace &lt;span class="paren4"&gt;(&lt;span class="default"&gt;span &lt;span class="string"&gt;&amp;quot;This was more &amp;quot;&lt;/span&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;em &lt;span class="string"&gt;&amp;quot;complex&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    `&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;self::*&amp;quot;&lt;/span&gt; insert-into &lt;span class="string"&gt;&amp;quot;, don&amp;#x27;t you think?&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

&lt;span class="paren1"&gt;(&lt;span class="default"&gt;serialize-sxml &lt;span class="paren2"&gt;(&lt;span class="default"&gt;change doc&lt;/span&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;output:&lt;/span&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;current-output-port&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The arguments to &lt;tt&gt;sxml-modify&lt;/tt&gt; comprise a mini-DSL, representing actions to take on the XML document.  Each action is a list; first an &lt;a href="http://www.w3.org/TR/xpath/" class="external"&gt;XPath&lt;/a&gt; expression which selects node(s) from the document, then the name of the action to perform, followed by the value to use for this action.  Each action is executed in sequence, so the XPath expression is relative to the previous action's node set, a little like how &lt;i&gt;chaining&lt;/i&gt; works in the excellent &lt;a href="http://jquery.com/" class="external"&gt;jQuery&lt;/a&gt; library.  Actually, I think there are still some lessons in convenience to learn from jQuery, but that's a different story.&lt;/p&gt;
&lt;p&gt;Let's invoke the program and see what happens:&lt;/p&gt;
&lt;pre&gt;&lt;tt&gt;$ cat welcome.xml
&amp;lt;div id=&amp;quot;welcome&amp;quot; class=&amp;quot;section&amp;quot;&amp;gt;
 &amp;lt;span&amp;gt;Hello, &amp;lt;strong class=&amp;quot;affectionately&amp;quot;&amp;gt;dear&amp;lt;/strong&amp;gt;friends.&amp;lt;/span&amp;gt;
 &amp;lt;span&amp;gt;This is a &amp;amp;lt;simple&amp;amp;gt; example.&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;
$ csi -s convert.scm &amp;lt; welcome.xml
&amp;lt;div id=&amp;quot;good-bye&amp;quot; class=&amp;quot;section&amp;quot;&amp;gt;
 &amp;lt;span&amp;gt;Goodbye, &amp;lt;strong class=&amp;quot;affectionately&amp;quot;&amp;gt;dear&amp;lt;/strong&amp;gt;friends.&amp;lt;/span&amp;gt;
 &amp;lt;span&amp;gt;This was more &amp;lt;em&amp;gt;complex&amp;lt;/em&amp;gt;, don't you think?&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Not too shabby for a 10-line program!&lt;/p&gt;
&lt;p&gt;Unfortunately, there's a catch.  Originally, I planned to use the Atom feed from the previous section as input, but it turns out that the modifications sub-language doesn't support passing a namespace map to the underlying XPath library.  Also, I was unable to use an &lt;a href="http://wiki.call-cc.org/eggref/4/sxpath" class="external"&gt;sxpath&lt;/a&gt; expression instead of a standard string XPath expression.  This could be bad documentation (the &lt;a href="http://modis.ispras.ru/Lizorkin/sxml-tutorial.html#hevea:modif" class="external"&gt;docs for SXML modifications&lt;/a&gt; are pretty sparse), or perhaps it's a lack of support for namespaces. A quick look at the source seems to confirm the latter. The lack of support for sxpath expressions is also serious and indicates how &amp;quot;random&amp;quot; the selection of tools in SSAX really is; some of these tools don't even support each other!  Luckily, it looks like both limitations aren't fundamental, and could be addressed by a (small?) change in the tools.&lt;/p&gt;
&lt;p&gt;I mentioned earlier that the SSAX project is a loose collection of tools with incoherent documentation.  My failure in figuring out how to combine namespaces with SXML modifications or use the sxpath DSL from the &amp;quot;SXML modifications&amp;quot; DSL helps point out the importance of a good, robust, and well-documented tool set.  This might possibly be more important than a good DSL; if nobody can use your DSL, it might just as well not exist.&lt;/p&gt;&lt;a href="#wrapping-up"&gt;
&lt;h2 id="wrapping-up"&gt;Wrapping up&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;The following rules can be distilled from the SXML design:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Do not slavishly translate surface syntax to S-expressions, but model the &lt;i&gt;structure&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;Eliminate or generalize all features that are strictly unnecessary.&lt;/li&gt;
&lt;li&gt;When generalizations demand new names, pick ones that are invalid in the source language, but try to borrow familiar conventions from the domain.&lt;/li&gt;
&lt;li&gt;When generating output, ensure structural integrity by escaping all content.&lt;/li&gt;
&lt;li&gt;People will avoid clumsy DSLs, to the point of falling back on string manipulation.&lt;/li&gt;
&lt;li&gt;No matter how well-designed your DSL is, it &lt;i&gt;needs&lt;/i&gt; good tools and documentation.&lt;/li&gt;
&lt;li&gt;DSLs within the same domain should be mutually supportive.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;There are still many aspects of XML we barely touched upon.  However, this post is already long enough, and my knowledge of XML (and SXML) only goes so far, so we won't go into more detail.  Of course, you can always dig in and find out more yourself; there are plenty of links in this document you can use to study the subjects.&lt;/p&gt;</content>
    <id>tag:more-magic,2012-08-05:/posts/lispy-dsl-sxml.html</id>
    <published>2012-08-05T14:07:01Z</published>
    <title type="text">Designing Lispy DSLs, part 2: SXML</title>
    <updated>2012-08-05T14:07:01Z</updated>
    <link href="https://www.more-magic.net/posts/lispy-dsl-sxml.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;Setting up this blog was a good excuse to try out &lt;a href="http://wiki.call-cc.org/eggref/4/scss" class="external"&gt;SCSS&lt;/a&gt;, which I'd been meaning to do for quite a long time.  Working with SCSS and exploring its limitations got me thinking about what makes a good Lispy DSL (domain specific language).  This post is the first of a series.  Today we'll look at SCSS; in future installments we'll explore other examples of Lispy DSLs.&lt;/p&gt;
&lt;p&gt;The idea behind SCSS isn't unique; by generating CSS from a more powerful language you get to use the abstraction systems provided by that language.  Abstractions are sorely needed when writing advanced CSS; for example, you often need to use one color in many different situations.  In plain CSS, you need to repeat this color value for every usage and, if a few instances need to change, you must go find and replace them.  You can imagine it's easy to forget one, or to replace too many!  Where HTML makes it easy to write semantically meaningful content (by assigning IDs and classes, for example), CSS doesn't have any way to indicate how style elements logically relate.&lt;/p&gt;
&lt;p&gt;As an interesting side note, one of the creators of CSS, Bert Bos, thinks that &amp;quot;real-language&amp;quot; features are unnecessary in CSS.  He goes as far as saying &lt;a href="http://www.w3.org/People/Bos/CSS-variables" class="external"&gt;constants&lt;/a&gt; shouldn't even be added to CSS. His main argument basically boils down to &lt;i&gt;other people are stupid so&lt;/i&gt; &lt;b&gt;you&lt;/b&gt; &lt;i&gt;don't get to use advanced features, either&lt;/i&gt;.  Luckily, many people disagree and have written their own server-side preprocessing languages.&lt;/p&gt;
&lt;p&gt;Some of these projects (like &lt;a href="http://lesscss.org/" class="external"&gt;Less&lt;/a&gt; and &lt;a href="http://sass-lang.com/" class="external"&gt;Sass&lt;/a&gt;) take the approach of adding their own syntax extensions to &amp;quot;plain&amp;quot; CSS, while others (like &lt;a href="http://sass-lang.com/docs/yardoc/file.INDENTED_SYNTAX.html" class="external"&gt;an older syntax of Sass&lt;/a&gt;) design their own custom language that's inspired by the concepts in CSS but quite different in syntax. All these projects are purely about &lt;i&gt;generating&lt;/i&gt; CSS from another language.  But we are smug Scheme weenies, and to us &lt;a href="http://c2.com/cgi/wiki?DataAndCodeAreTheSameThing" class="external"&gt;code and data are one and the same&lt;/a&gt;. A typical Schemer would prefer not just to generate CSS from SCSS, but to represent CSS in a &lt;i&gt;first-class value&lt;/i&gt;, so that it can be manipulated at will.  And that's exactly what SCSS offers... at first glance.&lt;/p&gt;&lt;a href="#the-devil-is-in-the-many-messy-details"&gt;
&lt;h2 id="the-devil-is-in-the-many-messy-details"&gt;The devil is in the many, messy details&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;When you first look at CSS, it seems like a simple enough language. Indeed, the &lt;a href="http://www.w3.org/TR/1998/REC-CSS2-19980512/grammar.html" class="external"&gt;core syntax&lt;/a&gt; &lt;i&gt;is&lt;/i&gt; rather simple.  Each rule set has selectors separated by commas followed by declarations between curly braces, separated by semicolons:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight css-language"&gt;#my-id, p.my-class, div {
  &lt;span class="variable"&gt;background-color&lt;/span&gt;: green;
  &lt;span class="variable"&gt;width&lt;/span&gt;: 10em;
  &lt;span class="variable"&gt;margin-left&lt;/span&gt;: 5px;
  &lt;span class="variable"&gt;border&lt;/span&gt;: 1px solid rgb(0, 128, 0);
}&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;There are three selectors here: the first one selects any element with the id attribute &amp;quot;&lt;tt&gt;my-id&lt;/tt&gt;&amp;quot;, the second one selects every &lt;tt&gt;p&lt;/tt&gt; element (paragraph) which has &amp;quot;&lt;tt&gt;my-class&lt;/tt&gt;&amp;quot; listed in its class attribute.  The third one simply selects all &lt;tt&gt;div&lt;/tt&gt; elements.  The declarations are simple property/value pairs which determine how the selected elements will be displayed.&lt;/p&gt;
&lt;p&gt;In Scheme, we can easily represent this as lists of items, where each item is a list of selectors and values, and that's exactly what SCSS does:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;`&lt;span class="paren1"&gt;(&lt;span class="default"&gt;css+
   &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;= id &lt;span class="string"&gt;&amp;quot;my-id&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;p &lt;span class="paren5"&gt;(&lt;span class="default"&gt;= class my-class&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; div&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;background-color &lt;span class="string"&gt;&amp;quot;#008000&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="comment"&gt;; Should we use string values
&lt;/span&gt;    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;color green&lt;/span&gt;)&lt;/span&gt;                &lt;span class="comment"&gt;; for classes and colors, or symbols?
&lt;/span&gt;    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;width &lt;span class="string"&gt;&amp;quot;10em&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;margin-left &lt;span class="string"&gt;&amp;quot;5px&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;border &lt;span class="string"&gt;&amp;quot;1px solid rgb(0, 128, 0)&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;One neat feature that's added by most of these CSS preprocessors is that you can &lt;i&gt;nest&lt;/i&gt; items.  This places the full expression of their parent before the sub-item, which means that item will only match the selector within its parent:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;`&lt;span class="paren1"&gt;(&lt;span class="default"&gt;css+
   &lt;span class="paren2"&gt;(&lt;span class="default"&gt;div
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;border &lt;span class="string"&gt;&amp;quot;1px solid rgb(0, 128, 0)&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;// &lt;span class="paren6"&gt;(&lt;span class="default"&gt;= class &lt;span class="string"&gt;&amp;quot;some-child&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren5"&gt;(&lt;span class="default"&gt;// &lt;span class="paren6"&gt;(&lt;span class="default"&gt;= id &lt;span class="string"&gt;&amp;quot;some-other-child&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
     &lt;span class="paren4"&gt;(&lt;span class="default"&gt;color orange&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This compiles to the following CSS:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight css-language"&gt;div {
  &lt;span class="variable"&gt;border&lt;/span&gt;: 1px solid rgb(0, 128, 0);
}

div .some-child,
div #some-other-child {
  &lt;span class="variable"&gt;color&lt;/span&gt;: orange
}&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;When looking at the examples we should start to get a funny feeling. Aside from the fact that the selector syntax is rather heavy on parens which makes it hard to read even for a Schemer, there are a few problems.  The first problem is the fact that we are representing the property values as flat strings (or symbols).  This means you can't easily, say, find all the elements that have a particular color somewhere in their values without &lt;i&gt;very&lt;/i&gt; heavy additional parsing (in CSS, &lt;tt&gt;green&lt;/tt&gt;, &lt;tt&gt;rgb(0,128,0)&lt;/tt&gt; and &lt;tt&gt;#008000&lt;/tt&gt; all mean exactly the same thing).  You also can't easily compose declarations with variables without doing string manipulations, which mostly defeats the point of using a first-class representation:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;&lt;span class="paren1"&gt;(&lt;span class="default"&gt;&lt;i&gt;&lt;span class="symbol"&gt;let&lt;/span&gt;&lt;/i&gt; &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;company-color &lt;span class="string"&gt;&amp;quot;#008000&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren3"&gt;(&lt;span class="default"&gt;page-width 1000&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren3"&gt;(&lt;span class="default"&gt;logo-size 20&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
  `&lt;span class="paren2"&gt;(&lt;span class="default"&gt;css+
     &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;= class &lt;span class="string"&gt;&amp;quot;menu&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;border-left ,&lt;span class="paren5"&gt;(&lt;span class="default"&gt;sprintf &lt;span class="string"&gt;&amp;quot;1px solid ~A&amp;quot;&lt;/span&gt; ,company-color&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren4"&gt;(&lt;span class="default"&gt;width ,&lt;span class="paren5"&gt;(&lt;span class="default"&gt;sprintf &lt;span class="string"&gt;&amp;quot;~Apx&amp;quot;&lt;/span&gt; &lt;span class="paren6"&gt;(&lt;span class="default"&gt;- page-width logo-size&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
     &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;= class &lt;span class="string"&gt;&amp;quot;whatever&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren5"&gt;(&lt;span class="default"&gt;background ,&lt;span class="paren6"&gt;(&lt;span class="default"&gt;sprintf &lt;span class="string"&gt;&amp;quot;url(&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;img/back.png&lt;/span&gt;&lt;span class="string"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;) no-repeat 10px 20px ~A&amp;quot;&lt;/span&gt;
                            ,company-color&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The second problem is that strings, being directly injected into the CSS, don't get &amp;quot;escaped&amp;quot;.  This means you can't take any user input (let's say a font name, or a color value) and use this in a declaration value; this can destroy your entire layout if it contains a semicolon or curly brace - at best an annoying bug, at worst, a security issue.  You might just put everything in one string for all the difference it makes:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;`&lt;span class="paren1"&gt;(&lt;span class="default"&gt;css+
   &lt;span class="paren2"&gt;(&lt;span class="default"&gt;.my-class
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;color &lt;span class="string"&gt;&amp;quot;#222; list-style-type: circle; margin-left: 5px&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The third &amp;quot;problem&amp;quot; points us in the right direction. The &lt;tt&gt;border&lt;/tt&gt;-property is actually a &lt;a href="http://www.w3.org/TR/1998/REC-CSS2-19980512/about.html#shorthand" class="external"&gt;shorthand property&lt;/a&gt;. The &lt;tt&gt;border&lt;/tt&gt; declaration from the first example breaks down into the following full declarations:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight css-language"&gt;html {
  &lt;span class="variable"&gt;border-top&lt;/span&gt;: 1px solid rgb(0, 128, 0);
  &lt;span class="variable"&gt;border-right&lt;/span&gt;: 1px solid rgb(0, 128, 0);
  &lt;span class="variable"&gt;border-bottom&lt;/span&gt;: 1px solid rgb(0, 128, 0);
  &lt;span class="variable"&gt;border-left&lt;/span&gt;: 1px solid rgb(0, 128, 0);
}&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Unfortunately, this decomposition is impossible to do in SCSS without parsing the property's string values.  Besides, even if we were to do that, these properties themselves are shorthands, too!  For example, the &lt;tt&gt;border-top&lt;/tt&gt; declaration itself breaks down into these declarations:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight css-language"&gt;html {
  &lt;span class="variable"&gt;border-top-width&lt;/span&gt;: 1px;
  &lt;span class="variable"&gt;border-top-style&lt;/span&gt;: solid;
  &lt;span class="variable"&gt;border-top-color&lt;/span&gt;: rgb(0, 128, 0);
}&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;This is similar to how in Scheme &lt;i&gt;macros&lt;/i&gt; can rewrite convenient notation to a simpler core language.  The better approach would be to compile down to the core CSS forms rather than trying to use these complex properties directly.&lt;/p&gt;
&lt;p&gt;To get this far, we'd have to decompose everything to its simplest form and assemble more complex properties in terms of simpler ones. In CSS, each property basically has its own free-form &amp;quot;value&amp;quot; syntax which can get quite complex.  Some examples:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight css-language"&gt;html {
  &lt;span class="comment"&gt;/**
   * Images can be full URIs (dragging in another pretty large RFC), which can
   * *optionally* be quoted (why all this unnecessary optional stuff?)
   */&lt;/span&gt;
  &lt;span class="variable"&gt;background-image&lt;/span&gt;: url(&lt;span class="string"&gt;&amp;quot;path/to/image.png&amp;quot;&lt;/span&gt;);

  &lt;span class="comment"&gt;/* You can use named &amp;quot;counters&amp;quot; (what, there are no variables in CSS?!) */&lt;/span&gt;
  &lt;span class="variable"&gt;content&lt;/span&gt;: &lt;span class="string"&gt;&amp;quot;Chapter &amp;quot;&lt;/span&gt; counter(my-chapter-counter) &lt;span class="string"&gt;&amp;quot;. &amp;quot;&lt;/span&gt;;
  &lt;span class="variable"&gt;counter-increment&lt;/span&gt;: my-chapter-counter;      &lt;span class="comment"&gt;/* Add 1 to chapter */&lt;/span&gt;

  &lt;span class="comment"&gt;/**
   * Lists of font names (strings), separated by spaces and possibly quoted.
   * Also, a restricted set of specially-defined &amp;quot;generic font families&amp;quot;
   * like serif, fantasy (WTF) and monospace, and even specially-defined
   * &amp;quot;system fonts&amp;quot; like status-bar, small-caption, icon, and menu.
   */&lt;/span&gt;
  &lt;span class="variable"&gt;font-family&lt;/span&gt;: Helvetica, &lt;span class="string"&gt;&amp;quot;Comic Sans MS&amp;quot;&lt;/span&gt;, fantasy, small-caption;

  &lt;span class="comment"&gt;/**
   * Different size types: em, ex, px, pt, in, cm, mm, percentage, unit-less.
   * Margins and paddings take 1, 2, 3 or 4 values which expand into -top,
   * -right, -bottom and -left.
   */&lt;/span&gt;
  &lt;span class="variable"&gt;margin&lt;/span&gt;: 1px 2em 30% 0;
}&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Seriously, who comes &lt;i&gt;up&lt;/i&gt; with this stuff?  I'm not saying any of these things are useless, but from a language design standpoint, this seems rather excessive.  CSS 3 is even more extreme; there, &amp;quot;image&amp;quot; value-types get so complex that &lt;a href="http://dev.w3.org/csswg/css3-images" class="external"&gt;they need their own separate document&lt;/a&gt; to specify.  The &lt;a href="http://dev.w3.org/csswg/css3-background/#background" class="external"&gt;background&lt;/a&gt; shorthand property grew in complexity as well.  Two examples from these drafts (quick, what visual effect do these have?  No cheating):&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight css-language"&gt;html {
  &lt;span class="variable"&gt;list-style-image&lt;/span&gt;:
      radial-gradient(circle, #006, #00a 90%, #0000af 100%, white 100%);
  &lt;span class="variable"&gt;background&lt;/span&gt;: url(&lt;span class="string"&gt;&amp;quot;chess.png&amp;quot;&lt;/span&gt;) 40% / 10em gray round fixed border-box;
}&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Finally, the CSS3 animations &lt;a href="http://www.w3.org/TR/css3-animations/" class="external"&gt;draft spec&lt;/a&gt; adds a completely new syntax element for key frames.  This is the only place in plain CSS where curly brace sections are nested inside other curly brace sections.&lt;/p&gt;
&lt;p&gt;This highly variable and ever-changing aspect of the syntax means that it's quite an open-ended language.  This makes it quite hard to cover all future extensions.  The one point that gives me hope is the fact that all this complexity &lt;i&gt;is&lt;/i&gt; built up out of a set of core &amp;quot;atoms&amp;quot; like &lt;a href="http://www.w3.org/TR/1998/REC-CSS2-19980512/syndata.html#length-units" class="external"&gt;length units&lt;/a&gt;, &lt;a href="http://www.w3.org/TR/1998/REC-CSS2-19980512/syndata.html#uri" class="external"&gt;URIs&lt;/a&gt; and &lt;a href="http://www.w3.org/TR/1998/REC-CSS2-19980512/syndata.html#color-units" class="external"&gt;colors&lt;/a&gt;. These atoms do not seem to change too much.&lt;/p&gt;
&lt;p&gt;This observation shows us an opportunity for a better CSS DSL; we could try to map these atoms to suitable Scheme values, possibly ignoring the details of how complex values are composed out of these atoms.  This is basically what the W3C did with their &lt;a href="http://www.w3.org/TR/DOM-Level-2-Style/css.html" class="external"&gt;CSS DOM&lt;/a&gt; API. Taking a good look at this DOM API might help to get some inspiration, even if the API itself is unwieldy and un-Lispy (it's very OOP-ish).&lt;/p&gt;
&lt;p&gt;In a language without a small set of well-defined atoms, you will need special parsers and generators for each separate type. This is very confusing to people.  I know, because this is exactly the approach I took for representing HTTP headers in &lt;a href="http://wiki.call-cc.org/eggref/4/intarweb#header-types" class="external"&gt;intarweb&lt;/a&gt;. I don't consider intarweb to be a &lt;i&gt;true&lt;/i&gt; DSL since it doesn't really have &amp;quot;native&amp;quot; syntax for its header values.  Everything passes through construction procedures which &lt;i&gt;do&lt;/i&gt; accept &amp;quot;native&amp;quot; values.  However, it does illustrate the point; I've had several requests for explanation of how to do common (what I thought were) simple things or &amp;quot;just give me a way to write out the raw header&amp;quot;.  That's a DSL failure; DSLs ought to be straightforward and easy to understand, yet powerful.&lt;/p&gt;
&lt;p&gt;I like to think that Intarweb isn't a &lt;i&gt;complete&lt;/i&gt; failure, because when working with intarweb, once everything is parsed, it's often rather nice not to have to deal with parsing anymore.  Things like cookies or authentication attributes are notoriously hard to parse correctly, and if everyone up the entire server-side HTTP stack needs to roll their own parser, that's a lot of wasted effort, and a lot of inconsistent implementations with their own bugs.  Manipulating these values is also a breeze and never involves string manipulation.&lt;/p&gt;&lt;a href="#what-might-a-better-scss-look-like"&gt;
&lt;h2 id="what-might-a-better-scss-look-like"&gt;What might a better SCSS look like?&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;From our new understanding of the nature of CSS, let's try improving it iteratively.  For starters, we would like to use parenthetical notation for everything.  Plain strings should be disallowed except where they are appropriate and are &lt;i&gt;always&lt;/i&gt; quoted and escaped. Making this simple change gives us the following:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;`&lt;span class="paren1"&gt;(&lt;span class="default"&gt;scss+
   &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;= class &lt;span class="string"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;= class &lt;span class="string"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;border-left-color &lt;span class="paren4"&gt;(&lt;span class="default"&gt;rgb 0 128 0&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;border-left-width &lt;span class="paren4"&gt;(&lt;span class="default"&gt;em 1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="comment"&gt;;; unsure whether we should allow this shorthand..
&lt;/span&gt;    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;border-right &lt;span class="paren4"&gt;(&lt;span class="default"&gt;px 1&lt;/span&gt;)&lt;/span&gt; solid ,orange&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;width &lt;span class="paren4"&gt;(&lt;span class="default"&gt;px ,&lt;span class="paren5"&gt;(&lt;span class="default"&gt;- page-width sidebar-width&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;// p&lt;/span&gt;)&lt;/span&gt;
     &lt;span class="paren4"&gt;(&lt;span class="default"&gt;color green&lt;/span&gt;)&lt;/span&gt;
     &lt;span class="paren4"&gt;(&lt;span class="default"&gt;font-family #&lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;Helvetica&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Comic Sans MS&amp;quot;&lt;/span&gt; sans-serif&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;I've used vectors to describe sequences of things, whereas composite declarations like border-right are simply expressions with more than two subexpressions.  Built-ins like &lt;tt&gt;sans-serif&lt;/tt&gt; and &lt;tt&gt;green&lt;/tt&gt; are symbols.  As you can see, because there are no strings, lengths can be calculated without having to perform string manipulation.  Another valid approach would be having a special &amp;quot;color&amp;quot; object type with associated procedures that operate on them.  If we wanted to do this, SCSS could export variables with color definitions so that &lt;tt&gt;green&lt;/tt&gt; is simply an alias for &lt;tt&gt;(rgb 0 128 0)&lt;/tt&gt;, and you could perform &amp;quot;color-algebraic&amp;quot; operations:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;`&lt;span class="paren1"&gt;(&lt;span class="default"&gt;scss+
   &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;= class &lt;span class="string"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; &lt;span class="paren4"&gt;(&lt;span class="default"&gt;= class &lt;span class="string"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;border-left-color ,&lt;span class="paren4"&gt;(&lt;span class="default"&gt;rgb 0 128 0&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;   &lt;span class="comment"&gt;; &amp;quot;rgb&amp;quot; is a constructor procedure now
&lt;/span&gt;    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;border-left-width ,&lt;span class="paren4"&gt;(&lt;span class="default"&gt;em 1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;          &lt;span class="comment"&gt;; So are &amp;quot;em&amp;quot;...
&lt;/span&gt;    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;border-right ,&lt;span class="paren4"&gt;(&lt;span class="default"&gt;px 1&lt;/span&gt;)&lt;/span&gt; solid ,orange&lt;/span&gt;)&lt;/span&gt; &lt;span class="comment"&gt;; .. and &amp;quot;px&amp;quot;
&lt;/span&gt;    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;&lt;span class="paren4"&gt;(&lt;span class="default"&gt;// p&lt;/span&gt;)&lt;/span&gt;
     &lt;span class="paren4"&gt;(&lt;span class="default"&gt;color ,green&lt;/span&gt;)&lt;/span&gt;
     &lt;span class="comment"&gt;;; A green background which is darker by 50%
&lt;/span&gt;     &lt;span class="paren4"&gt;(&lt;span class="default"&gt;background-color ,&lt;span class="paren5"&gt;(&lt;span class="default"&gt;darken green .5&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
     &lt;span class="paren4"&gt;(&lt;span class="default"&gt;font-family #&lt;span class="paren5"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;Helvetica&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Comic Sans MS&amp;quot;&lt;/span&gt; sans-serif&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;I can't think of any useful operations on font types, so I've kept &lt;tt&gt;sans-serif&lt;/tt&gt; a symbol here.  How far you want to go depends on your goals, and involves striking a balance between ease of use, safety, and power.  For instance, you could define a separate type for everything, including fonts, but that would make it harder to use.  It would also make it harder to introduce mistakes, especially if the CSS generator will validate while rendering.  However, strict validation also means allowing extensions (like those from CSS3) becomes harder!&lt;/p&gt;
&lt;p&gt;The selector syntax could use some love too, but I'm less critical of that. The basic idea is fine; it can extend to include arbitrary selectors.  It currently supports the &lt;tt&gt;+&lt;/tt&gt; sibling and &lt;tt&gt;&amp;gt;&lt;/tt&gt; child selector as well as the class and id comparisons.  Because these operators are in the operator position of a list, adding new ones is as simple as adding a new procedure in Scheme.  A pseudo-selector like &lt;tt&gt;p:first-child&lt;/tt&gt; for example could simply be translated to &lt;tt&gt;(: p first-child)&lt;/tt&gt; without breaking anything else.&lt;/p&gt;
&lt;p&gt;Right now selectors are simply grouped by adding an extra set of parens around them to put them in a list.  Using a visual cue like &lt;tt&gt;and&lt;/tt&gt; or &lt;tt&gt;or&lt;/tt&gt; to indicate grouping might help for readability, as would getting rid of the &lt;tt&gt;//&lt;/tt&gt; selector for hierarchical nesting.  As long as we make sure all selectors are unused property names there's no ambiguity in simply nesting a new rule inside another one:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;`&lt;span class="paren1"&gt;(&lt;span class="default"&gt;scss+
   &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;= class &lt;span class="string"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;color ,orange&lt;/span&gt;)&lt;/span&gt;
   &lt;span class="paren3"&gt;(&lt;span class="default"&gt;div
    &lt;span class="paren4"&gt;(&lt;span class="default"&gt;margin-left ,&lt;span class="paren5"&gt;(&lt;span class="default"&gt;px 1&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="paren5"&gt;(&lt;span class="default"&gt;or &lt;span class="paren6"&gt;(&lt;span class="default"&gt;= class &lt;span class="paren1"&gt;(&lt;span class="default"&gt;or &lt;span class="string"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
         &lt;span class="paren6"&gt;(&lt;span class="default"&gt;= id qux&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
     &lt;span class="paren5"&gt;(&lt;span class="default"&gt;border-left-color ,&lt;span class="paren6"&gt;(&lt;span class="default"&gt;rgb 0 128 0&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
     &lt;span class="paren5"&gt;(&lt;span class="default"&gt;font-family #&lt;span class="paren6"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;Helvetica&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Comic Sans MS&amp;quot;&lt;/span&gt; sans-serif&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Instead of repeating the class selection, we just put the &lt;tt&gt;(or ...)&lt;/tt&gt; around the class, which is a nice abbreviation, but overall I'm not too happy about this version, so let's back up a step.&lt;/p&gt;
&lt;p&gt;We can't &lt;i&gt;guarantee&lt;/i&gt; that the selector symbols will remain unused as property values, because we don't know what property names the CSS spec might add in the future.  We should strive to avoid potential clashes with future extensions.  Also, dropping the &lt;tt&gt;//&lt;/tt&gt; makes it harder to traverse an SCSS tree and perform manipulations since the traversal code would need a full list of all known selectors.  So after all, it looks like it's better to keep the &lt;tt&gt;//&lt;/tt&gt;.  But we &lt;i&gt;can&lt;/i&gt; drop some unnecessary parens by taking the previous example and just putting the &lt;tt&gt;//&lt;/tt&gt; before the selector.  Since it's been modified to be &lt;i&gt;one s-expression&lt;/i&gt;, we can do that.  We can also allow the &lt;tt&gt;=&lt;/tt&gt; selector to accept &lt;i&gt;any&lt;/i&gt; attribute (not just classes).  While we're at it, this selector should also accept multiple values to avoid repetition:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight scheme-language"&gt;`&lt;span class="paren1"&gt;(&lt;span class="default"&gt;scss+
   &lt;span class="paren2"&gt;(&lt;span class="default"&gt;&lt;span class="paren3"&gt;(&lt;span class="default"&gt;or &lt;span class="paren4"&gt;(&lt;span class="default"&gt;~= p class &lt;span class="string"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;    &lt;span class="comment"&gt;; Change to (has-word? p class &amp;quot;foo&amp;quot;) ?
&lt;/span&gt;        &lt;span class="paren4"&gt;(&lt;span class="default"&gt;+ div &lt;span class="paren5"&gt;(&lt;span class="default"&gt;= p class &lt;span class="string"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt; my-attr &lt;span class="string"&gt;&amp;quot;qux&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;border-left-color ,&lt;span class="paren4"&gt;(&lt;span class="default"&gt;rgb 0 128 0&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;font-family #&lt;span class="paren4"&gt;(&lt;span class="default"&gt;&lt;span class="string"&gt;&amp;quot;Helvetica&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;Comic Sans MS&amp;quot;&lt;/span&gt; sans-serif&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

    &lt;span class="paren3"&gt;(&lt;span class="default"&gt;// &lt;span class="paren4"&gt;(&lt;span class="default"&gt;= * class &lt;span class="paren5"&gt;(&lt;span class="default"&gt;or &lt;span class="string"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt; &lt;span class="string"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;
        &lt;span class="paren4"&gt;(&lt;span class="default"&gt;color ,orange&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;

   &lt;span class="paren2"&gt;(&lt;span class="default"&gt;div
      &lt;span class="paren3"&gt;(&lt;span class="default"&gt;display &lt;i&gt;&lt;span class="symbol"&gt;block&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;)&lt;/span&gt;
      &lt;span class="paren3"&gt;(&lt;span class="default"&gt;// span
          &lt;span class="paren4"&gt;(&lt;span class="default"&gt;text-align left&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The example above also shows the extensibility of operators by adding the &lt;tt&gt;~=&lt;/tt&gt; selector (a very unschemely name...).  Let's see the CSS this would compile to:&lt;/p&gt;
&lt;pre&gt;&lt;tt class="highlight css-language"&gt;p[class~=&lt;span class="string"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;],
div + p.bar[my-attr=&lt;span class="string"&gt;&amp;quot;qux&amp;quot;&lt;/span&gt;] {
  &lt;span class="variable"&gt;border-left-color&lt;/span&gt;: rgb(0, 128, 0);
  &lt;span class="variable"&gt;font-family&lt;/span&gt;: &lt;span class="string"&gt;&amp;quot;Helvetica&amp;quot;&lt;/span&gt;, &lt;span class="string"&gt;&amp;quot;Comic Sans MS&amp;quot;&lt;/span&gt;, sans-serif;
}

p[class~=&lt;span class="string"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;] *.foo,
p[class~=&lt;span class="string"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;] *.bar,
div + p.bar[my-attr=&lt;span class="string"&gt;&amp;quot;qux&amp;quot;&lt;/span&gt;] *.foo,
div + p.bar[my-attr=&lt;span class="string"&gt;&amp;quot;qux&amp;quot;&lt;/span&gt;] *.bar {
  &lt;span class="variable"&gt;color&lt;/span&gt;: orange;
}

div {
  &lt;span class="variable"&gt;display&lt;/span&gt;: block;
}

div span {
  &lt;span class="variable"&gt;text-align&lt;/span&gt;: left;
}&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;That's not too bad!  There's a lot of redundancy in the resulting CSS that we abstracted away via the combination of shortened &lt;tt&gt;or&lt;/tt&gt;-alternatives and hierarchical nesting.  The original SCSS also had this hierarchical nesting, by the way, so this type of redundancy is already avoided even by using a slightly flawed DSL.&lt;/p&gt;
&lt;p&gt;In CSS, the &lt;tt&gt;#foo&lt;/tt&gt; and &lt;tt&gt;.bar&lt;/tt&gt; syntaxes are shorthands for selecting on IDs and classes, because these are so common.  There is no &lt;i&gt;technical&lt;/i&gt; need to support these shortcuts, so if this makes your design less clean, you can always drop them and opt to use the generic selectors everywhere.  For IE6 and other crippled browsers, the renderer could detect class selection and rewrite it to the short syntax.  You could always consider extending the Scheme reader to get the same brevity at a higher level, while keeping SCSS itself simple (not that I would &lt;i&gt;recommend&lt;/i&gt; doing that, but the option exists).&lt;/p&gt;&lt;a href="#lessons-learned"&gt;
&lt;h2 id="lessons-learned"&gt;Lessons learned&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;I will try to wrap up each blog post in this series by listing the general design rules that we can extract from the DSL under discussion.  To wrap an existing language like CSS into a DSL, the following approach seems useful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First, identify the atomic building blocks.  If there are many, this may spell trouble.&lt;/li&gt;
&lt;li&gt;Decide which building blocks are essential to be represented &amp;quot;first class&amp;quot; in a structured way, and which can be unstructured strings or symbols (Lisp's atoms).&lt;/li&gt;
&lt;li&gt;Determine the combination rules of these atoms and how to translate this to s-expressions.&lt;/li&gt;
&lt;li&gt;Think about whether you want to rely on the host language and expose shorthands and abstractions directly, or if you want to rely on Scheme's abstraction facilities.&lt;/li&gt;
&lt;li&gt;If possible, look in what direction the language evolved, and how it has been extended in the past.  Your design must be able to accommodate changes in these directions.&lt;/li&gt;
&lt;li&gt;Finally, use parentheses and &amp;quot;noise symbols&amp;quot; sparingly, but effectively!  Try striking a balance between notation and manipulation convenience.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;I realize that some of the things I've said in this post might be contradictory.  I might be too vague and hand-wavery in some places. Hell; many things are probably &lt;i&gt;bloody obvious&lt;/i&gt; to some of you.  But the main point is that it's important to remember that &lt;i&gt;design is hard&lt;/i&gt;, and will always involve trade-offs.&lt;/p&gt;
&lt;p&gt;I hope that you understand that when designing a DSL you'd better think about what use cases you want it to support before considering how to answer a particular design question.  It's very easy to get carried away and overdesign a DSL, but another pitfall is to have too little design (like SCSS, in my opinion).  Next time we'll look at a design that's pretty close to ideal, and show that even with that, there are some problems.&lt;/p&gt;</content>
    <id>tag:more-magic,2012-07-28:/posts/lispy-dsl-scss.html</id>
    <published>2012-07-28T19:39:04Z</published>
    <title type="text">Designing Lispy DSLs, part 1: SCSS</title>
    <updated>2012-07-28T19:39:04Z</updated>
    <link href="https://www.more-magic.net/posts/lispy-dsl-scss.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
  <entry>
    <author>
      <name>Peter Bex</name>
    </author>
    <content type="html">
&lt;p&gt;Welcome to my renewed website.  I've decided to stop procrastinating and instead of rolling my own blog software I decided to simply take &lt;a href="http://wiki.call-cc.org/egg/hyde" class="external"&gt;Hyde&lt;/a&gt; and actually start blogging!&lt;/p&gt;&lt;a href="#the-quest-for-better-blogging-software"&gt;
&lt;h2 id="the-quest-for-better-blogging-software"&gt;The quest for better blogging software&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;I've started writing blog software from scratch about three times by now.  The first time I attempted making what one could call a &amp;quot;clone&amp;quot; of Wordpress or other similar blogging &amp;quot;platforms&amp;quot;.  This means that software would be based on &lt;i&gt;other people's&lt;/i&gt; preconceptions of what blogging software is supposed to be like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dynamically generated from a database.&lt;/li&gt;
&lt;li&gt;A web-based backend interface for writing posts, with a session-based login system.&lt;/li&gt;
&lt;li&gt;A full-fledged rights system.&lt;/li&gt;
&lt;li&gt;HTML as markup language, maybe with a WYSIWYG editor since HTML is so painful to write manually.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;I think I started with this project because I thought that having a fully featured web publishing platform written in &lt;a href="http://www.call-cc.org" class="external"&gt;Chicken Scheme&lt;/a&gt; would ensure all the prerequisites for building &amp;quot;large-scale&amp;quot; web applications would be available, thereby possibly making it more useful for my dayjob.  There are still quite a few components that are missing, like a proper &amp;quot;safe HTML&amp;quot; filter (useful for when you have guest bloggers who shouldn't be able to post using all available HTML tags), &lt;tt&gt;multipart/form-data&lt;/tt&gt; support for file uploads, a good e-mailing library, etc.&lt;/p&gt;
&lt;p&gt;Of course this project was doomed to fail because this type of software is nowhere near my ideal workflow; I prefer tapping away at the keyboard using my current favorite text editor, &lt;a href="http://www.gnu.org/software/emacs/" class="external"&gt;Emacs&lt;/a&gt;. The text-input interface provided by most web browsers is pretty horrible and if you close the window or refresh the page by mistake, you lose everything you just typed in, too!  Like most programming geeks, I also generally prefer storing stuff in a version control system so I can track the edit history of my writings.  Of course if I was going to make a &lt;i&gt;serious&lt;/i&gt; blogging platform, I'd have to replicate most features from a version control system too...&lt;/p&gt;&lt;a href="#return-to-sanity"&gt;
&lt;h2 id="return-to-sanity"&gt;Return to sanity&lt;/h2&gt;&lt;/a&gt;
&lt;p&gt;Sick and tired of writing tedious HTML nonsense I was never going to enjoy using in the first place, I decided to get started on my second attempt, more attuned to my own preferences with severely scaled-down scope:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dynamically assembled content from simple textfiles with minimal markup (using &lt;a href="http://wiki.call-cc.org/egg/svnwiki-sxml" class="external"&gt;simplified svnwiki syntax&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Content stored in a version control tool like &lt;a href="http://mercurial.selenic.com" class="external"&gt;mercurial&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;No comments, since on technical blogs people often just bicker and argue in comments anyway, and you also end up fighting lots spam - that's not worth my time.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;I almost managed to get this &amp;quot;finished&amp;quot; (I was at the the eternal &lt;i&gt;90% done&lt;/i&gt; stage of development), but then I decided it's silly to write something like that when there's a perfectly useful alternative.  The &lt;i&gt;not invented here&lt;/i&gt; approach to software &lt;b&gt;ends here, now&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;One of the advantages of a static website generator rather than using something dynamic is that there can be no security problems related to the blog software.  Hyde generates flat HTML files which are served up by the webserver.  There is no dynamic content at all.  This is also really fast, since all the parsing of blog posts and the conversion to HTML is done at &amp;quot;compilation time&amp;quot;.  And instead of pouring infinite amounts of time into writing code I'll never use, I can focus on the content (and spend way too many hours tweaking the styling...)&lt;/p&gt;
&lt;p&gt;The current site sticks to minimalism everywhere; even the &lt;a href="/archive.html" class="internal"&gt;archive page&lt;/a&gt; is very straightforward, listing only the titles and dates of &lt;i&gt;all&lt;/i&gt; posts.  If it turns out I write so many posts that a fancier paging system is necessary, I'll write it at that moment, but not a moment sooner!&lt;/p&gt;</content>
    <id>tag:more-magic,2012-07-22:/posts/a-new-beginning.html</id>
    <published>2012-07-22T16:14:35Z</published>
    <title type="text">A new beginning</title>
    <updated>2012-07-22T16:14:35Z</updated>
    <link href="https://www.more-magic.net/posts/a-new-beginning.html" rel="alternate" type="application/xhtml+xml" />
  </entry>
</feed>