{"id":13739691,"url":"https://github.com/dedbox/racket-algebraic","last_synced_at":"2026-01-05T20:39:37.239Z","repository":{"id":62423988,"uuid":"140366463","full_name":"dedbox/racket-algebraic","owner":"dedbox","description":"Algebraic structures for untyped Racket","archived":false,"fork":false,"pushed_at":"2024-07-16T23:20:14.000Z","size":314,"stargazers_count":76,"open_issues_count":36,"forks_count":7,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-30T11:43:58.991Z","etag":null,"topics":["algebraic","functional-programming","racket"],"latest_commit_sha":null,"homepage":"","language":"Racket","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dedbox.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-07-10T02:30:45.000Z","updated_at":"2024-12-28T22:03:00.000Z","dependencies_parsed_at":"2022-11-01T18:01:00.163Z","dependency_job_id":null,"html_url":"https://github.com/dedbox/racket-algebraic","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dedbox%2Fracket-algebraic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dedbox%2Fracket-algebraic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dedbox%2Fracket-algebraic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dedbox%2Fracket-algebraic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dedbox","download_url":"https://codeload.github.com/dedbox/racket-algebraic/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245467229,"owners_count":20620210,"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":["algebraic","functional-programming","racket"],"created_at":"2024-08-03T04:00:36.577Z","updated_at":"2026-01-05T20:39:32.220Z","avatar_url":"https://github.com/dedbox.png","language":"Racket","funding_links":[],"categories":["Data Structures","Racket"],"sub_categories":[],"readme":"# Algebraic Racket\n[![Racket Package](https://img.shields.io/badge/raco%20pkg-algebraic-red.svg)](https://pkgd.racket-lang.org/pkgn/package/algebraic)\n[![Documentation](https://img.shields.io/badge/read-docs-blue.svg)](http://docs.racket-lang.org/algebraic/)\n[![Build Status](https://travis-ci.org/dedbox/racket-algebraic.svg?branch=master)](https://travis-ci.org/dedbox/racket-algebraic)\n[![Coverage Status](https://coveralls.io/repos/github/dedbox/racket-algebraic/badge.svg?branch=master)](https://coveralls.io/github/dedbox/racket-algebraic?branch=master)\n\nA Racket extension for untyped algebraic data structures.\n\n## What is Algebraic Racket?\n\nAlgebraic structures provide the operational under-pinnings for algebraic\ndata types. What's missing is the static typing constraints.\n\nThe current release provides a `#lang algebraic/racket/base` that extends\n`#lang racket/base` with:\n\n  1. First class, lexically scoped, naturally ordered data constructors,\n     and\n\n  2. A consistent destructuring syntax for functions and macros.\n\n### Algebraic Data\n\nAs the name implies, Algebraic Racket works with two kinds of structure:\nsums and products.\n\n```\n(data Maybe (Nothing Just))\n```\n\nThis defines a sum named `Maybe` and two constituent products named `Nothing`\nand `Just`. It also defines three membership predicates named `Maybe?`,\n`Nothing?`, and `Just?` for recognizing products and their instances.\n\nThe elements of a sum are ordered by position so they can be compared and\nsorted.\n\n```\n\u003e (data A-Z (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z))\n\u003e (let ([Πs (shuffle (data-\u003elist (sum A-Z)))])\n    (values Πs (sort Πs data-less-than?)))\n'(G O M W V C Q H T K F S Y U Z A B R J N E P X I L D)\n'(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)\n```\n\n```\n\u003e (data Z-A (Z Y X W V U T S R Q P O N M L K J I H G F E D C B A))\n\u003e (let ([Πs (shuffle (data-\u003elist (sum Z-A)))])\n    (values Πs (sort Πs data-less-than?)))\n'(R C U N Y Z X L A K D H B J S V E G I W O M P Q F T)\n'(Z Y X W V U T S R Q P O N M L K J I H G F E D C B A)\n```\n\nThe products `Nothing` and `Just` can be matched against directly or they can\nbe used to construct instances of the products.\n\nAn instance is a transparent data structure that resembles a tagged tuple.\nAlgebraic Racket imposes no restrictions on the type or number of arguments\naccepted by a product.\n\n```\n\u003e (values (Just) (Just 1) (Just 1 2))\n(Just)\n(Just 1)\n(Just 1 2)\n```\n\n### Destructuring Syntax\n\nAlgebraic Racket provides `φ`/`phi` and `function` forms (and multi-arg\nvariants) which extend the variable binding sites of the `λ`/`lambda` form\nwith support for pattern-based destructuring.\n\n```\n\u003e (define maybe\n    (function*\n      [(n _ Nothing) n]\n      [(_ f (Just x)) (f x)]))\n\u003e (values\n   (maybe #f values (Just 123))\n   (maybe #f values Nothing))\n123\n#f\n```\n\nIt also provides `μ`/`mu` and `macro` forms for syntax transformers.\n\n```\n\u003e (define-syntax unroll-pow\n    (μ* (b:number p:number) '(* #,@(make-list (var p) #'b))))\n\u003e (unroll-pow 2 5)\n'(* 2 2 2 2 2)\n```\n\n#### Destructuring Patterns\n\nPatterns for literal data are designed to look and feel as similar as possible\nto the terms they match, including:\n\n- Plain old Racket structs\n\n- Unquoted literal values: boolean, number, string, bytes, char\n\n- Unquoted containers that look like literals: pair, list, vector, hash\n\n- Quoted data, including symbols\n\n- Quasiquoted data with escapes\n\nOther notable features include:\n\n- Pattern guards, aliases, rest args, and wildcard/variable naming conventions\n  all have a consistent look and feel across all function and macro forms.\n\n- Macros also support ellipsis patterns and the `:syntax-class` naming\n  convention. Use\n  [`syntax/parse`](https://docs.racket-lang.org/syntax/stxparse.html?q=syntax%2Fparse)\n  to define your own classes.\n\n- Regular expression patterns for functional string processing.\n\n## Installation and Use\n\nAlgebraic Racket is distributed in the\n[`algebraic`](https://pkgd.racket-lang.org/pkgn/package/algebraic) package in\nthe official Racket package repository. It can be installed from DrRacket's\npackage manager, or with `raco pkg` from the command line.\n\n```\nraco pkg install algebraic\n```\n\nTo start using Algebraic Racket, set the initial line of your Racket source\nfile to:\n\n```\n#lang algebraic/racket/base\n```\n\nThe package is fully documented, including a tutorial series of interpreters\ndeveloped for and with Algebraic Racket.\n\n## Related Work\n\n### Plain old Racket structs\n\n[Prefab](https://docs.racket-lang.org/reference/structures.html?q=prefab#%28tech._prefab%29)\nstruct types are globally scoped, which has been a problem for me in the past.\nNon-prefab structs are better in that regard, except basic features like type\nhierarchies and functional updaters have a tendency to interfere with each\nother.\n\nAlgebraic data constructors are lexically scoped and have no fixed arity.\nInstances of algebraic data are always transparent.\n\nDespite their differences, plain old Racket structs work pretty well with\nAlgebraic Racket's destructuring syntax. They're always there when you need\nthem.\n\n### Hackett\n\n[Hackett](https://docs.racket-lang.org/hackett/index.html) is an excellent\nplatform for pure, lazy functional programming in the Racket software\necosystem. If I needed pure and lazy evaluation semantics today, I'd try\nHackett before considering Haskell seriously again. Having said that, I don't\nusually want pure and lazy evaluation semantics.\n\nWouldn't it be nice if I could import just the features I wanted from Hackett\nand ignore the rest? That is the promise of language-oriented programming,\nafter all. For all I know, it's possible now.\n\nUnfortunately, it isn't yet possible to mix and match off-the-shelf features\nto comprise a tool as robust as Hackett (at least, that isn't Hackett itself).\nAlgebraic Racket is a step in that direction.\n\n### Typed Racket\n\n[Typed Racket](https://docs.racket-lang.org/ts-guide/index.html) is a robust\nplatform with a broad scope, and it keeps getting better. The type system\noffers the static analyses I care about and the documentation is excellent.\nAfter spending some time building interpreters in Typed Racket, I decided I\nstill wanted something else for two reasons:\n\n1. Fumbling with types for common Racket idioms (like `apply`) became a\n   distraction, and\n\n2. Uncompiled code loads very slowly.\n\nThis may say more about my ignorance of Typed Racket than anything else.\nNonetheless, Algebraic Racket takes advantage of my intuition for Haskell\nsyntax while staying responsive enough for rapid iterative exploratory\nprogramming.\n\n### Redex\n\n[Redex](https://docs.racket-lang.org/redex/index.html) is a domain-specific\nlanguage for semantics engineering. It does a lot more for the semantics\nengineer than Algebraic Racket ever will, like typesetting and testing\nautomation.\n\nOn the other hand, developing full applications with Redex is probably not for\nthe faint of heart. With Algebraic Racket, you get all the bells and whistles\nof `#lang racket/base` and then some.\n\n## Project Goals\n\nAlgebraic Racket is the first major milestone in a larger effort to produce a\ncomplete language-oriented toolkit for integrating algebraic structure into\nmore sophisticated designs.\n\nThe project aims to:\n\n1. Implement and document the forms, functions, and syntax classes comprising\n   Algebraic Racket for maximum potential reuse.\n\n2. Support the development of modular type systems and other language-facing\n   components as libraries.\n\n## Contributing\n\nPull requests of any size are welcome. For help creating one, please start a\nthread on\n[racket-users](https://groups.google.com/forum/#!forum/racket-users). For\nmajor changes, please open an\n[issue](https://github.com/dedbox/racket-algebraic/issues) first to discuss\nwhat you would like to change.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdedbox%2Fracket-algebraic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdedbox%2Fracket-algebraic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdedbox%2Fracket-algebraic/lists"}