{"id":16318530,"url":"https://github.com/vic/rex","last_synced_at":"2025-10-25T18:30:22.491Z","repository":{"id":57543821,"uuid":"70412585","full_name":"vic/rex","owner":"vic","description":"Concatenative Elixir macro language.","archived":false,"fork":false,"pushed_at":"2017-02-20T23:07:14.000Z","size":84,"stargazers_count":5,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-31T10:04:27.051Z","etag":null,"topics":["concatenative-language","elixir","experiment","syntax"],"latest_commit_sha":null,"homepage":"https://hex.pm/packages/rex","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vic.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":"2016-10-09T15:34:35.000Z","updated_at":"2020-05-19T20:11:42.000Z","dependencies_parsed_at":"2022-08-27T19:10:40.504Z","dependency_job_id":null,"html_url":"https://github.com/vic/rex","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vic%2Frex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vic%2Frex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vic%2Frex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vic%2Frex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vic","download_url":"https://codeload.github.com/vic/rex/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238191668,"owners_count":19431465,"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":["concatenative-language","elixir","experiment","syntax"],"created_at":"2024-10-10T22:23:48.850Z","updated_at":"2025-10-25T18:30:17.225Z","avatar_url":"https://github.com/vic.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Rex - Concatenative elixir macro language.\n\n\u003ca href=\"https://travis-ci.org/vic/rex\"\u003e\u003cimg src=\"https://travis-ci.org/vic/rex.svg\"\u003e\u003c/a\u003e\n[![help maintain this lib](https://img.shields.io/badge/looking%20for%20maintainer-DM%20%40vborja-663399.svg)](https://twitter.com/vborja)\n\n\n![rex](https://cloud.githubusercontent.com/assets/331/19221774/310460ee-8e0f-11e6-864b-0a4f2c34b5b2.png)\n\nRex is a [concatenative language](http://concatenative.org) built with Elixir macros.\n\nBeing powered by Elixir macros means that Rex has no parser of its own as it just\nuses valid Elixir syntax and thus can be embedded on any elixir program.\n\n## Installation\n\n[Available in Hex](https://hex.pm/packages/rex), the package can be installed as:\n\n  1. Add `rex` to your list of dependencies in `mix.exs`:\n\n    ```elixir\n    def deps do\n      [{:rex, \"~\u003e 0.1.0\"}]\n    end\n    ```\n\n## Stack based\n\nRex is stack based, that is all Rex functions take a list and return another list.\n\nThe topmost element in a stack is the one at index zero, for example, for\n`[1, 2, 3]` the top of the stack is `1`. Most Rex functions will operate on\ntop-most elements as they need and then push the result back to the top.\n\n\nInside the `rex` macro, the `~\u003e` operator indicates the order in which to push\nvalues or operators on to the top of the stack.\n\nFor example, `rex(1 ~\u003e 2 ~\u003e add)` would result on the following \n`[add, 2, 1]` stack that when executed will yield `[3]`.\n\nSo the `~\u003e` allows post-fix notation (operands first, operator last) syntax.\nThis is the preferred way as most concatenative languages are postfix, but\nRex also has a `\u003c~` operator which just pushes values in the reverse order:\n`rex(add \u003c~ 2 \u003c~ 1)` will result on `[add, 2, 1]`.\n\n\nThe following example uses functions from `Rex.Core` for stack manipulation\nand `Rex.Math` that defines aliases to standard elixir math operators.\n\n```elixir\niex\u003e [4, 5] |\u003e rex(3 ~\u003e 2 ~\u003e 1 ~\u003e add ~\u003e mul ~\u003e swap)\n[4, 9, 5] \n```\n\nMore examples available as [tests](https://github.com/vic/rex/blob/master/test/rex_test.exs)\n\n## Words\n\nIn concatenative languages, functions are refered to as *words*.\n\nInside an Elixir module, once you have `include Rex`'d\nyou can call `drex` to define a new _word_ that acts either as a\n*stack shuffler* or as an *operator on the stack*.\n\nTo define a stack *shuffling* word, the syntax is:\n\n```elixir\n    # (example from `Rex.Stack.swap/1`)\n    drex swap(a, b)     (b, a)\n```\n\n\nTo define a stack *operator* you use the `~\u003e` or `\u003c~` syntax:\n\n```elixir\n    # pushes 1 then 2 then performs adition\n    drex three        1 ~\u003e 2 ~\u003e Kernel.+/2\n\n    # pushes 2 then performs multiplication\n    # expecting a first value already on stack (ie. partial function)\n    drex double       Kernel.*/2 \u003c~ 2\n```\n\n\nAs *operators* are the most frequent types of words you will be creating,\nthe following *concatenative* syntax is supported:\n\n```elixir\n    # This will multiply the second element on the stack\n    # and then print the final stack state to stdout.\n    drex double_second  swap double swap show\n```\n\nHowever, if you want to also push an integer or any other Elixir literal,\ntrying something like `3 double` wont work because its not valid Elixir syntax.\nBut you can use the `do` notation for `drex`:\n\n\n```elixir\n      drex sixsix do\n        3\n        double dup Kernel.*/2\n      end\n```\n\nis exactly the same as:\n\n```elixir\n      drex sixsix  3 ~\u003e double ~\u003e dup ~\u003e Kernel.*/2\n```\n\nThe `do` form is peferred for large words. Most likely you'll just want to\nkeep them short as concatenative programs are very composable.\n\n#### [Pointless programming](https://en.wikipedia.org/wiki/Tacit_programming)\n\nWith Rex you can write point-free functions.\n\n```elixir\ndrex sumr     List.foldr/3 \u003c~ (\u0026Kernel.+/2) \u003c~ 0\n\nassert [6] == sumr([1, 2, 3])\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvic%2Frex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvic%2Frex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvic%2Frex/lists"}