# Competitive programming in Nim

Updated in 2022-10.

In the afternoon, I came cross the Nim programming language again on Lobsters. I first learned some basics of the language in 2015, but had not touched it since then.

"Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula.", according to its website.

Basic features: parametric polymorphism. Advanced features: macros (including term-rewriting macros), compile-time function execution, effect system, concepts

An idea popped into my mind: why not solve some coding challenges in Nim?

As a niche language, it is not supported on many coding challenge websites. Fortunately, the Nim compiler generates C code. With a small amount of work, we can build a self-contained C source file suitable for submission.

Let's take a LeetCode challenge as an example. We write the main algorithm in Nim and use the emit pragma to write a C wrapper.

Then, create a self-contained C file with the approach described on https://zeta.su/posts/amalgamating-nim-programs/.

## Install opam

Follow https://opam.ocaml.org/doc/Install.html and run opam init.

## Build CIL

Clone https://github.com/goblint/cil. Use a modestly recent version of ocaml or pick a recent ocaml release from opam switch list-available.

## Patch nimbase.h

Copy lib/nimbase.h to ~/Util/Nim. Comment out a visibility attribute.

In 2021 goblint-CLI did not handle #define _GNU_SOURCE 1 but it can now.

## Generate C amalgamation

On Linux the Nim compiler calls gcc by default. We replace gcc with a CIL wrapper to generate a merged C file.

Then run nim c -d:danger --gc:arc -d:useMalloc a.nim to generate a_comb.c. -d:useMalloc avoids Nim's own memory manager and can greatly decrease the C code size. There are several choices for --mm, but --mm:arc can genreate the smallest C code.

a_comb.c looks like:

The LeetCode environment includes some glibc headers like <stdio.h> which result in some conflicts due to duplicate definitions of struct _IO_FILE and some GNU extern inline functions. Let's write a Nim program to remove the duplicate definitions.

Finally, run { echo '/*'; cat a.nim; echo '*/'; cat amalgamation.c; } | xclip -i -selection clipboard and paste the content into the LeetCode editor:) Well, the Nim source is not really needed but it is useful for archive purposes.

## Minimization

Now let's decrease the size to make the amalgamation fit into more platforms.

clang-format safely removes whitespace and makes the program smaller.

To further decrease the source code length, we can shorten function, variables, and type names. See C minifier with Clang.

## Old notes

If CIL fails to handle some syntax, use another deduplicator: