{"id":23344367,"url":"https://github.com/rec/nmr","last_synced_at":"2026-03-02T11:31:16.750Z","repository":{"id":37576882,"uuid":"491969800","full_name":"rec/nmr","owner":"rec","description":"🌐 Name all canonical things 🌐","archived":false,"fork":false,"pushed_at":"2026-02-02T18:59:26.000Z","size":237,"stargazers_count":0,"open_issues_count":3,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-03T08:20:59.027Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rec.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELIST","contributing":null,"funding":"FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"rec"}},"created_at":"2022-05-13T16:32:53.000Z","updated_at":"2026-02-02T18:59:29.000Z","dependencies_parsed_at":"2023-01-30T01:45:37.596Z","dependency_job_id":"5d80b6cc-3028-4fa1-860f-429ca1157e16","html_url":"https://github.com/rec/nmr","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/rec/nmr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rec%2Fnmr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rec%2Fnmr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rec%2Fnmr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rec%2Fnmr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rec","download_url":"https://codeload.github.com/rec/nmr/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rec%2Fnmr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30000028,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-02T11:09:27.951Z","status":"ssl_error","status_checked_at":"2026-03-02T11:08:53.255Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-21T06:26:25.930Z","updated_at":"2026-03-02T11:31:16.605Z","avatar_url":"https://github.com/rec.png","language":"Python","funding_links":["https://github.com/sponsors/rec"],"categories":[],"sub_categories":[],"readme":"🔢 `nmr`: name all canonical things 🔢\n\nGive each canonical thing a unique English name using non-repeating words from a\nshort list of common, short English words... or use a word list of your choice.\n\nThe word list is here: https://github.com/rec/nmr/blob/main/words.txt\n\n\nCanonical things include but are not limited to:\n\n* numbers\n* fractions\n* times, dates, time intervals\n* lat/long positions on the earth\n* IP addresses\n* UUIDs\n\nOther unimplemented possibilities:\n\n* Phone numbers\n* Periodic table\n* Chemical compounds(?) (probably not worth the huge effort)\n* Pieces of music! (my original motivating example)\n\n\nShorter or simpler things should generally be represented by shorter names.\n\nExtending this to your own domain is easy and you can either add it to this\ncodebase or write your own code and easily plug in in.\n\nInstalls both a module named `nmr` and an executable called `nmr.py`\n\n# EXAMPLE\n\n``` python\nimport nmr\n\nassert nmr(0) == ['the']\nassert nmr(2718281828) == ['the', 'race', 'tie', 'hook']\n\nfor i in range(-2, 3):\n    print(i, ':', *nmr(i))\n\n# Prints\n#   -2 : to\n#   -1 : of\n#   0 : the\n#   1 : and\n#   2 : a\n```\n\n# HOW IT WORKS\n\nAll of this involves the same trick over and over again - counting using positional notation:\nhttps://en.wikipedia.org/wiki/Positional_notation\n\nBy default `nmr` has 1628 different words, which you can think of as 1628 different\ndigits.\n\nThere's a wrinkle that makes things harder: the author decided that repeating\nwords was unaesthetic, so counting is a little trickier, but you don't have to\nunderstand how it's done.\n\nWith repeating words eliminated, 1628 is the minimum total number of words\nneeded to be able to represent all 64-bit integers with at most six words.\n\n\nConversion runs as follows.\n\nFirst you take your type, whatever it is, and figure out a way to represent it as a\nnumber in positional notation, where perhaps the digits have different values.\n\nSuppose you're wanting to represent the time of the day, down to milliseconds.\n\nYou represent it as a four digit number: hours, minutes, seconds, milliseconds\n\nNext, you take the positional number, and evaluate it into a \"type-relative number\",\na number that makes sense only within this type.\n\nFor example, to represent the time 15:11:55.823, we'd evaluate the number\n`((((15 * 60) + 11) * 60 + 55) * 1000 + 823)` to get the type relative number,\nbut this number might mean something completely different for say, lat-long.\n\nNow, each type also gets its own fixed \"type identifier number\" and that gets combined\nwith the type-relative number to give a new number, the `nmr` number which is unique\nover all types.\n\nThen that `nmr` number is encoded into a non-repeating sequence of words from the\nword list, which is the `nmr` name.\n\n----\n\nIn the reverse direction, a `nmr` name is given, and it's converted back into an `nmr`\nnumber, then split into the type identifier number and type-relative number.\n\nThe type identifier number is used to look up which type is being decoded, and then\nthe type-relative number is decoded into the positional number, and finally\nback into the original type.\n\n----\n\nYou are guaranteed that for each original canonical thing, T, there is a unique\ncanonical name, and that decoding that name will always reproduce exactly the\nsame thing.\n\nIt's mathematically\nan [injection](https://en.wikipedia.org/wiki/Bijection,_injection_and_surjection).\n\nOn the other hand, if you start with a random name and try to decode, a data type\nisn't required to give any guarantees at all.\n\nYou aren't even guaranteed that the decoding will return anything - some names just\nwon't correspond even to a known type. If a name can be decoded to a known type,\nthat type decoder might still not be able to come up with a type. Or, if it comes\nup with a type, that type might have a different canonical name.\n\nThis is all good because it makes it really easy to whip up an encoder/decoder, but for\nthe basic encoders included with the program, we can offer a better guarantee: that we\ncan always decode any any type-relative number and return an instance of the type, even\nif we weren't given a canonical name.\n\nSeparately, we add a \"type wrapping\" feature to the main program so that unknown type\nidentifier numbers just wrap repeated over known type identifiers - again, this will\nnever be a canonical name.\n\nWith those features, it means you can type random names into the program, and see what\nsort of thing you get.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frec%2Fnmr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frec%2Fnmr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frec%2Fnmr/lists"}