{"id":16965013,"url":"https://github.com/propensive/typonym","last_synced_at":"2025-04-11T23:02:43.574Z","repository":{"id":222337974,"uuid":"756962447","full_name":"propensive/typonym","owner":"propensive","description":"Collections raised to the type-level in Scala","archived":false,"fork":false,"pushed_at":"2025-01-25T16:47:33.000Z","size":662,"stargazers_count":3,"open_issues_count":4,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-20T01:38:46.501Z","etag":null,"topics":["collections","dependent-types","scala","type-level","type-level-programming"],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/propensive.png","metadata":{"files":{"readme":".github/readme.md","changelog":null,"contributing":".github/contributing.md","funding":null,"license":null,"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}},"created_at":"2024-02-13T16:37:34.000Z","updated_at":"2025-02-11T20:41:56.000Z","dependencies_parsed_at":"2024-02-13T18:10:26.014Z","dependency_job_id":"de6d13ef-cf86-4e2e-9dab-099949076ee5","html_url":"https://github.com/propensive/typonym","commit_stats":null,"previous_names":["propensive/typonym"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/propensive%2Ftyponym","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/propensive%2Ftyponym/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/propensive%2Ftyponym/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/propensive%2Ftyponym/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/propensive","download_url":"https://codeload.github.com/propensive/typonym/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239805886,"owners_count":19700203,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["collections","dependent-types","scala","type-level","type-level-programming"],"created_at":"2024-10-13T23:44:49.813Z","updated_at":"2025-02-20T08:31:38.858Z","avatar_url":"https://github.com/propensive.png","language":"Scala","readme":"[\u003cimg alt=\"GitHub Workflow\" src=\"https://img.shields.io/github/actions/workflow/status/propensive/typonym/main.yml?style=for-the-badge\" height=\"24\"\u003e](https://github.com/propensive/typonym/actions)\n[\u003cimg src=\"https://img.shields.io/discord/633198088311537684?color=8899f7\u0026label=DISCORD\u0026style=for-the-badge\" height=\"24\"\u003e](https://discord.com/invite/MBUrkTgMnA)\n\u003cimg src=\"/doc/images/github.png\" valign=\"middle\"\u003e\n\n# Typonym\n\n__Collections raised to the type-level in Scala__\n\nWhen writing macros or generic type-level code, we often need a way to\nstatically represent collections of values, without them to existing at runtime\nand requiring allocation on the heap. Scala's `Tuple` type provides a generic\nway of representing a heterogeneous sequence of values at the type-level, but\nthe inline or macro code that's necessary to work with them—in particular, to\ndecompose them into values—can be intricate, fragile and repetitive. _Typonym_\nmakes it easy to convert between value-level and type-level representations of\nthree collection types, `List`s, `Set`s and `Map`s, as well as straigtforward\nconversions of singleton literal types.\n\n## Features\n\n- Provides type-level encodings of `List`s, `Set`s and `Map`s\n- Convert between runtime values and static types\n- Automatically convert singleton literal types\n- Types can be trivially composed for more complex structures\n- Types may be reified from a static type in \"normal\" code\n- Types can also be converted from a `Type` or `TypeRepr` value from within a\n  macro implementation\n\n\n## Availability\n\n\n\n\n\n\n\n## Getting Started\n\nAll terms and types are defined in the `typonym` package:\n```scala\nimport typonym.*\n```\n\n### Application\n\nScala's rich type system may be used as a means of carrying static information\nfrom one point in the code to another, so that it may be used for static\nanalysis and to influence typechecking. Much as a _runtime value_ may be passed\nas a parameter to a method, and influence that method's _runtime behavior_, a\n_compiletime type_ may be passed as a type parameter, and affect how that\nmethod is typechecked.\n\nThe runtime behavior of a method is, assuredly, implemented with ordinary\ncalling and branching logic, operating on runtime values and runs, of course,\nat runtime. And we write almost all code this way because it's easier.\n\nIn contrast, typechecking behavior (ignoring, for a moment, its relationship\nwith the runtime behavior it constrains) may be implemented using type-level\nconstructs that operate on types, and are not so much _run_ as _applied_ at\n_compiletime_. This is a harder way of implementing logic: type-level\noperations are less powerful and less expressive than those available at\nruntime. So it is not ideal.\n\nHowever, macros offer the ability to define type-level behavior using the\npower, expressivity and simplicity of value-level code, which will be _run_ at\n_compiletime_.\n\nSuch code often benefits from collections, such as lists, sets and maps, which\npresents a need to represent such types in the type system, and to convert\nbetween types (both static types and value-level reflections of those types in\nmacros) and standard Scala collections of values.\n\n### Type-level Representations\n\nSingleton types of `Int`s, `String`s, `Double`s and `Boolean`s have a\nstraightforward isomorphism from their value-level to their type-level\nrepresentations.\n\nA Scala `List` will be encoded as a `Tuple` parameter to the `TypeList` type\nconstuctor. For example, the list, `List(\"one\", \"two\", \"three\")` would be\nrepresented as, `TypeList[(\"one\", \"two\", \"three\")]` (by trivially composing it\nwith the type-level representation of `String`s).\n\n### Reification\n\nTyponym offers two overloaded variants of the `reify` method for transforming\ntypes into values, to be invoked with a static type; or with an instance of\n`Type`, from within a macro implementation.\n\nFor example, to convert the `List` example above to a value, we could call,\n```scala\nval list: List[String] = reify[TypeList[(\"one\", \"two\", \"three\")]]\n```\nor in a more general context,\n```scala\ninline def printElements[ItemsType \u003c: TypeList[?]]: Unit =\n  reify[ItemsType].foreach(println)\n```\n\nSimilarly, within a macro, \n```scala\n\ndef printLongest[ItemsType \u003c: TypeList[?]: Type](using Quotes): Expr[Unit] =\n  val items: List[String] = reify(Type.of[ItemsType])\n  println(items.maxBy(_.length))\n  '{()}\n```\n\n\n## Status\n\nTyponym is classified as __embryotic__. For reference, Soundness projects are\ncategorized into one of the following five stability levels:\n\n- _embryonic_: for experimental or demonstrative purposes only, without any guarantees of longevity\n- _fledgling_: of proven utility, seeking contributions, but liable to significant redesigns\n- _maturescent_: major design decisions broady settled, seeking probatory adoption and refinement\n- _dependable_: production-ready, subject to controlled ongoing maintenance and enhancement; tagged as version `1.0.0` or later\n- _adamantine_: proven, reliable and production-ready, with no further breaking changes ever anticipated\n\nProjects at any stability level, even _embryonic_ projects, can still be used,\nas long as caution is taken to avoid a mismatch between the project's stability\nlevel and the required stability and maintainability of your own project.\n\nTyponym is designed to be _small_. Its entire source code currently consists\nof 77 lines of code.\n\n## Building\n\nTyponym will ultimately be built by Fury, when it is published. In the\nmeantime, two possibilities are offered, however they are acknowledged to be\nfragile, inadequately tested, and unsuitable for anything more than\nexperimentation. They are provided only for the necessity of providing _some_\nanswer to the question, \"how can I try Typonym?\".\n\n1. *Copy the sources into your own project*\n   \n   Read the `fury` file in the repository root to understand Typonym's build\n   structure, dependencies and source location; the file format should be short\n   and quite intuitive. Copy the sources into a source directory in your own\n   project, then repeat (recursively) for each of the dependencies.\n\n   The sources are compiled against the latest nightly release of Scala 3.\n   There should be no problem to compile the project together with all of its\n   dependencies in a single compilation.\n\n2. *Build with [Wrath](https://github.com/propensive/wrath/)*\n\n   Wrath is a bootstrapping script for building Typonym and other projects in\n   the absence of a fully-featured build tool. It is designed to read the `fury`\n   file in the project directory, and produce a collection of JAR files which can\n   be added to a classpath, by compiling the project and all of its dependencies,\n   including the Scala compiler itself.\n   \n   Download the latest version of\n   [`wrath`](https://github.com/propensive/wrath/releases/latest), make it\n   executable, and add it to your path, for example by copying it to\n   `/usr/local/bin/`.\n\n   Clone this repository inside an empty directory, so that the build can\n   safely make clones of repositories it depends on as _peers_ of `typonym`.\n   Run `wrath -F` in the repository root. This will download and compile the\n   latest version of Scala, as well as all of Typonym's dependencies.\n\n   If the build was successful, the compiled JAR files can be found in the\n   `.wrath/dist` directory.\n\n## Contributing\n\nContributors to Typonym are welcome and encouraged. New contributors may like\nto look for issues marked\n[beginner](https://github.com/propensive/typonym/labels/beginner).\n\nWe suggest that all contributors read the [Contributing\nGuide](/contributing.md) to make the process of contributing to Typonym\neasier.\n\nPlease __do not__ contact project maintainers privately with questions unless\nthere is a good reason to keep them private. While it can be tempting to\nrepsond to such questions, private answers cannot be shared with a wider\naudience, and it can result in duplication of effort.\n\n## Author\n\nTyponym was designed and developed by Jon Pretty, and commercial support and\ntraining on all aspects of Scala 3 is available from [Propensive\nO\u0026Uuml;](https://propensive.com/).\n\n\n\n## Name\n\nA typonym is a name derived from a type. Similarly, _Typonym_ derives a _value_\nfrom a type (and types from values).\n\nIn general, Soundness project names are always chosen with some rationale,\nhowever it is usually frivolous. Each name is chosen for more for its\n_uniqueness_ and _intrigue_ than its concision or catchiness, and there is no\nbias towards names with positive or \"nice\" meanings—since many of the libraries\nperform some quite unpleasant tasks.\n\nNames should be English words, though many are obscure or archaic, and it\nshould be noted how willingly English adopts foreign words. Names are generally\nof Greek or Latin origin, and have often arrived in English via a romance\nlanguage.\n\n## Logo\n\nThe logo shows the square brackets which usually delimit a type in Scala.\n\n## License\n\nTyponym is copyright \u0026copy; 2025 Jon Pretty \u0026 Propensive O\u0026Uuml;, and\nis made available under the [Apache 2.0 License](/license.md).\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpropensive%2Ftyponym","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpropensive%2Ftyponym","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpropensive%2Ftyponym/lists"}