{"id":13508552,"url":"https://github.com/taiansu/pipe_to","last_synced_at":"2025-10-21T15:10:05.190Z","repository":{"id":57533683,"uuid":"67824423","full_name":"taiansu/pipe_to","owner":"taiansu","description":"The enhanced elixir pipe operator which can specify the target position","archived":true,"fork":false,"pushed_at":"2021-09-14T15:20:04.000Z","size":92,"stargazers_count":85,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-01T08:33:27.767Z","etag":null,"topics":["elixir"],"latest_commit_sha":null,"homepage":"https://taiansu.github.io/pipe_to","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/taiansu.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-09-09T18:55:49.000Z","updated_at":"2023-09-01T08:26:47.000Z","dependencies_parsed_at":"2022-09-26T18:21:12.294Z","dependency_job_id":null,"html_url":"https://github.com/taiansu/pipe_to","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/taiansu%2Fpipe_to","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taiansu%2Fpipe_to/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taiansu%2Fpipe_to/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taiansu%2Fpipe_to/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/taiansu","download_url":"https://codeload.github.com/taiansu/pipe_to/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246314011,"owners_count":20757450,"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":["elixir"],"created_at":"2024-08-01T02:00:54.679Z","updated_at":"2025-10-21T15:10:04.816Z","avatar_url":"https://github.com/taiansu.png","language":"Elixir","funding_links":[],"categories":["Macros"],"sub_categories":[],"readme":"[![Build Status](https://github.com/taiansu/pipe_to/workflows/ci/badge.svg)](https://github.com/taiansu/pipe_to/actions)\n\n\n# Disclaimer\n\nStart from Elixir 1.12.0, we have [Kernel.then/2](https://hexdocs.pm/elixir/1.12.0/Kernel.html#then/2),\nwhich let us pipe into a partial application, nativately. We should follow the official convention\nwhile we could. For example:\n\n```elixir\n1\n|\u003e then(\u0026Enum.at([1, 2, 3], \u00261))\n\n5\n|\u003e then(\u0026Enum.take(1..10, \u00261))\n|\u003e Enum.reverse()\n```\n\nI'll maintain this library for legacy Elixir versions, until they reach their end of lifes.\n\nThanks for all the starts. Let's move on, live long and prosper.\n\n---\n\n# PipeTo\n\nThe enhanced pipe operator which can specify the target position.\n\n## Installation\n\nTo use PipeTo with your projects, edit your mix.exs file and add it as a dependency:\n\n```elixir\ndef deps do\n  [{:pipe_to, \"~\u003e 0.2\"}]\nend\n```\n\nThen run `mix deps.get`\n\n## Quick start\n\n* `import PipeTo` in your module,\n* pipe with `~\u003e`\n* use `_` to specify the target position of left-hand side expression.\n\n```elixir\n\u003e import PipeTo\n\u003e 1 ~\u003e Enum.at([1, 2, 3], _)\n# 2\n```\n\nIt works with pipe operator nicely.\n\n```elixir\n\u003e 5 ~\u003e Enum.take(1..10, _) |\u003e Enum.reverse()\n# [5, 4, 3, 2, 1]\n```\n\nIn fact, if you don't specify the position with `_`, it acts just like normal `|\u003e`\n```elixir\n\u003e [4, 8, 1] ~\u003e Enum.max()\n# 8\n```\n\n## Override the `Kernel.|\u003e/2`\nSince `~\u003e` is the enhanced pipe operator, you can override the `Kernel.|\u003e/2` with it.\n\n```elixir\ndefmodule Foo do\n  use PipeTo.Override\n\n  def bar do\n    2 |\u003e Enum.drop(1..10, _) |\u003e Enum.at(1)\n  end\nend\n\nFoo.bar\n# 4\n```\n\n## Performance\n\nuse `PipeTo` sightly faster then normal pipe in all these cases below. For the __case 2__ and __case 3__, I will guess\nthat anonymous function slow down the oridinary pipe. But it doesn't explain why in the _case 1_ `PipeTo` insignificantly faster\nthen ordinary pipe. Any ideas?\n\n### Case 1: Ordinary Pipe vs PipeTo without index\n\n![bench_1](https://cloud.githubusercontent.com/assets/241597/18638941/81e774ec-7ec4-11e6-9609-ed2c4747c3cf.png)\n\n### Case 2: Pipe with anonymous function vs PipeTo with index\n\n![bench_2](https://cloud.githubusercontent.com/assets/241597/18634414/621593f8-7eb3-11e6-8c31-2895efd150b8.png)\n\n### Case 3: Pipe with anonymous vs use PipeTo.Override\n\n![bench_3](https://cloud.githubusercontent.com/assets/241597/18634416/6217001c-7eb3-11e6-94dd-aacc9dec2ad1.png)\n\n## Disclaimer\n\n  I have read through the proposals of pipe operator enhancement on the [elixir-lang-core](https://groups.google.com/forum/#!forum/elixir-lang-core), like [this](https://groups.google.com/forum/#!searchin/elixir-lang-core/pipe$20argument%7Csort:relevance/elixir-lang-core/jKOJ1zUYwaE/SIKql6ybAQAJ), [this](https://groups.google.com/forum/#!searchin/elixir-lang-core/pipe$20argument|sort:relevance/elixir-lang-) or [this](https://groups.google.com/forum/#!searchin/elixir-lang-core/pipe$20argument|sort:relevance/elixir-lang-core/wTK072BdJus/GOUMaUrEEQAJ).\n\n  The reason I still want this is because the combination of curried function (or partial application) with pipe operator is so elegant, like [this F# example here](https://fsharpforfunandprofit.com/posts/partial-application/). Since Elixir doesn't have these mechnism, and also anonymous function call use `.()`, so syntactically (well, aesthetically) the only choice I have is to modify the pipe operator.\n\n## Is it any good?\n[Yes](https://news.ycombinator.com/item?id=3067434)\n\n## License\nApache 2\n\n## TODO\n* Discard the default operator, user should specify the operator expicitly, to work with lib like Witchcraft better.\n* Pipe into mutiple target at once\n* Pipe into target in nested expression, instead of only the shallowest level like now.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftaiansu%2Fpipe_to","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftaiansu%2Fpipe_to","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftaiansu%2Fpipe_to/lists"}