format

This library has the goal to bring the Common Lisp format directive to Go. This is work-in-progress, see the summary implementation table below for an overview on what is working and what not.

For a nice introduction to the Common Lisp format see https://en.wikipedia.org/wiki/Format_(Common_Lisp).

Example Code

import "github.com/ragnaroek/format/pkg"

ft.Sformat("~8r", 8) //returns "10"
ft.Sformat("~10,'#,'🥭,2:@X", 4099) //returns "####+10🥭03"

ft.Sformat("~r", 4343637058903381868) //returns "four quintillion three hundred forty-three quadrillion six hundred thirty-seven trillion fifty-eight billion nine hundred three million three hundred eighty-one thousand eight hundred sixty-eight"
ft.Sformat("~:@r", 2799) //returns "MMDCCLXXXXVIIII"
ft.Sformat("[email protected]", 2799) //returns "MMDCCXCIX"

Playground

Since the format directives can get complicated and the best way to figure them output is to play around with them the format playground was created:

playground.png

The playground is hosted here: https://ragnaroek.github.io/format/ The library is compiled to WASM to make it run on the browser.

Implementation Status

The directives listed below are already implemented:

~ Name Prefix args : @ :@ Note
~c Char Pretty Escape :@ not yet implemented
~% Newline # newline
~& Freshline # lines
~| Page # pages
~~ Tilde # ~
~r Radix mincol, padchar, comma-char, comma-interval Ordinal Roman Old Roman
~d Decimal mincol, padchar, comma-char, comma-interval
~b Binary mincol, padchar, comma-char, comma-interval
~o Octal mincol, padchar, comma-char, comma-interval
~x Hexadecimal mincol, padchar, comma-char, comma-interval
~f Float width, decimals, scale, overflow, pad Sign
~{ ~} Iteration : and @ not yet implemented

This table is derived from https://www.hexstreamsoft.com/articles/common-lisp-format-reference/clhs-summary/#subsections-summary-table, which was also a great help in the implementation of the directives so far. Many thanks to Jean-Philippe Paradis.

All other directives not mentioned in the table are not implemented yet.

Current work-in-progress

Implementing more directives.

Optimisation! format is currently 16% to 22% times slower than fmt for the standard cases. Currently 47% slower in the float performance.

BenchmarkFmtSimple-12       	18412630	        59.0 ns/op
BenchmarkFmtLong-12         	 5016384	       235 ns/op
BenchmarkFmtFloat-12        	 4191775	       293 ns/op
BenchmarkFormatSimple-12    	17161602	        68.5 ns/op
BenchmarkFormatLong-12      	 4237104	       286 ns/op
BenchmarkFormatFloat-12     	 2731093	       429 ns/op

You can run the benchmarks yourself with make bench. A history of benchmark results is collected in BENCHMARK.md.

Thanks

This software is open source (LGPLv3) and was made while listening to a lot of Rage against the Machine ✊🏿

GitHub

https://github.com/Ragnaroek/format