{"id":34833230,"url":"https://github.com/renatopp/pipelang","last_synced_at":"2026-05-21T12:05:59.330Z","repository":{"id":236413948,"uuid":"792564031","full_name":"renatopp/pipelang","owner":"renatopp","description":"An experimental language based on function chaining and generators to create lazy pipes.","archived":false,"fork":false,"pushed_at":"2024-04-28T17:39:08.000Z","size":2104,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-19T20:52:57.443Z","etag":null,"topics":["golang","language","pipe","programming"],"latest_commit_sha":null,"homepage":"https://pipe.r2p.dev","language":"Go","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/renatopp.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-27T00:06:59.000Z","updated_at":"2024-04-28T17:39:11.000Z","dependencies_parsed_at":"2024-06-19T12:38:23.204Z","dependency_job_id":"ca6fbb73-768d-433c-96ba-3f664a0c1243","html_url":"https://github.com/renatopp/pipelang","commit_stats":null,"previous_names":["renatopp/pipelang"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/renatopp/pipelang","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renatopp%2Fpipelang","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renatopp%2Fpipelang/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renatopp%2Fpipelang/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renatopp%2Fpipelang/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/renatopp","download_url":"https://codeload.github.com/renatopp/pipelang/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renatopp%2Fpipelang/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33299868,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-21T02:57:32.698Z","status":"ssl_error","status_checked_at":"2026-05-21T02:57:31.990Z","response_time":62,"last_error":"SSL_read: 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":["golang","language","pipe","programming"],"created_at":"2025-12-25T15:58:15.902Z","updated_at":"2026-05-21T12:05:59.323Z","avatar_url":"https://github.com/renatopp.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PIPE LANG\n\nPIPE Lang is an **experimental** language designed to handle streams of data in a compact and readable style. Focused on daily automation tasks, the goal is simplify the scripts that requires sequential (and eventually some parallel) steps.\n\n## Why should I use it?\n\nYou shouldn't. Feel free to try it, but at this point, the language is very unstable and more experimental than practical.\n\n## What does it look like?\n\n```haskell\n-- Euler problem 2: Find the sum of the even-valued terms in the Fibonacci sequence whose values do not exceed four million\nfn fib(x) {\n  return match x {\n    0: 0;\n    1: 1\n    x: fib(x-1) + fib(x-2)\n  }\n}\n\nrange()\n| map       fib\n| takeWhile x: x \u003c= 4_000_000\n| filter    x: x.IsEven()\n| sum\n```\n\nYou may try it out in [https://pipe.r2p.dev](https://pipe.r2p.dev).\n\n## The CLI\n\n```bash\n# Opens the REPL tool\npipe shell\n\n# Evaluate inline\npipe eval 'print(\"hi\")'\n\n# Run file\npipe run file.pp\n```\n\n## Features\n\n### The Type System\n\nPIPE is a strong dynamic typed language with minimal builtin types:\n\n```haskell\n-- They are all `Number` type\nnum1 := 100\nnum2 := 100.0\nnum3 := 1e10\n\n-- They are all `Boolean` type\nbool1 := true\nbool2 := false\n\n-- They are all `String` type\nstr1 := 'Single-quoted strings'\nstr2 := \"Single-quoted strings\"\nstr3 := `Raw Strings\nCan be Multiline`\n\n-- `List` type\nlist1 := List{}\nlist2 := [1, 2, 3, 4, 5]\nlist3 := ['a', 1, [3, true]]\n\n-- `Dict` type\ndict1 := Dict {}\ndict2 := { a=1, b=2, 3=4 }\n\n-- `Maybe`\nmaybe := Maybe(2)\nmaybe.Ok()\nmaybe.Error()\nmaybe.Value()\nmaybe.Result()\n\n-- `Stream` as the iterator object\nlist2.Elements() -- = \u003cStream\u003e\n```\n\nThe language uses Go short declaration style `:=`. Declared variables may be reassigned but only if the types match. Variables can be re-declared any time.\n\n```haskell\nvar := 'Im a string'\nvar = 2               -- will raise an error!\nvar := 2              -- redeclare var as a number, ok\n```\n\nTuples are used in assignments in an overly complex dynamics:\n\n```haskell\na, b    := 1, 2      -- a=1; b=2\na       := 1, 2      -- a=1; ignoring 2\na, b    := 1         -- error!\na, ...b := 1         -- a=1; b=[]\na, ...b := 1, 2, 3   -- a=1; b=[2, 3]\na, b    := [1, 2]... -- a=1; b=2\n```\n\nType conversion can be done explicitly:\n\n```haskell\nString(3)\nNumber('3')\nBool(3)\nStream([1, 2])\n```\n\n\n### Operations\n\nNotice that PIPE is strong typed, so operations can only be performed when involves two variables of the same type, with exception to equality, logical and concat operators\n\n```haskell\n-- Arithmetic\na + b\na - b\na / b\na * b\na % b -- mod\na ^ b -- pow\n\n-- Relational\na \u003c b\na \u003e b\na \u003c= b\na \u003e= b\na == b\na != b\na \u003c=\u003e b -- spaceship operator, returning -1, 0, 1 \n\n-- Logical\n!a\na and b\na or b\na xor b\n\n-- Other\na .. b -- concat as string\n```\n\n### Functions\n\nPretty much everything in the language is an expression, which returns something. An empty block `{}`, such as in ifs, for and functions, generates false as default, otherwise it will return the last executed expression.\n\n```haskell\n-- `return` keyword is optional. \nfn add(a, b) {\n  a + b\n}\n\n-- Function definition is just an expression\nadd := fn(a, b) {\n  a + b\n}\n\n-- Functions are high order and respect closures\nfn mult(x) {\n  fn (a, b) { (a + b)*x }\n}\nmult(2)(1, 5) -- = 12\n\n-- Lambda functions are definied by `:`\nlambda1 := a : a*2\nlambda2 := (a, b): a + b\n\n-- Shortcuts\nfn (a, b) {} -- Nameless\nfn ping {}   -- Parameterless\nfn {}        -- Nameless parameterless \n\n-- Generator functions return a `Stream` object, that is only\n-- evaluated when queried.\nfn OneTwoThree {\n  yield 1\n  yield 2\n  yield 3\n}\nstream := OneTwoThree()\nstream.Next() -- Maybe(1)\nstream.Next() -- Maybe(2)\nstream.Next() -- Maybe(3)\nstream.Next() -- Maybe(Error)\n```\n\n### Function Chaining (AKA pipe expressions)\n\nFunction chaining (or pipe expressions) are the core of the language, it uses the power of generator functions to create processors that evaluate streams of data sequentially in a lazy way.\n\n```haskell\n[1, 2, 3, 4]\n| filter x: x.IsEven()\n| map    x: x*2\n| sum\n-- = 12\n```\n\nThe code above is equivalent to `sum( map( filter( [1,2,3,4] , x:x.IsEven()) , x:x*2) )`.\n\nNote that pipes are just a compact way to call functions. This means that `a | b` is equivalent to `b(a)`. The pipe expression has an special notation, where the first identifier after the pipe is the function to be called, and the remaining of the elements in the line are the arguments (without call parenthesis to reduce clutter):\n\n- `a | b 1, 2, 3` is equivalent `b(a, 1, 2, 3)`\n- `a | b 2, (a, b): a+b` is equivalent `b(a, 2, \u003clambda\u003e)`\n\nMost of builtin functions that operate in pipes converts the first argument to a stream, forcing the generator, thus, forcing it to be lazy.\n\n### Flow Controls\n\nFlow controls are a mixture of go, python and rust:\n\n```haskell\n-- Simple conditional\nif a == b { ... }\n\n-- Conditional with additional expressions\n-- Notice that only the last expression is considered as conditional\nif a := b(); a { ... }\n\n-- Pattern matching\nmatch x, y {\n\t     0, 0: println('zero zero')\n\t_ as a, 0: println(a, 'zero')\n\t\t\t _, _: println('im done')\n}\n\n-- Infinite loop\nfor { ... }\n\n-- Simple for\nfor a == b { ... }\n\n-- For in stream\nfor a in stream { ... }\n```\n\n### Error Handling\n\nAny function can throw errors by using the `raise` keyword:\n\n```haskell\nfn explode {\n\traise 'error'\n}\n```\n\nIn order to capture this error, PIPE uses a wrap operator `?`:\n\n```haskell\nresult := explode()?\n\nif result.Error() {\n\t-- treat error\n}\n\nval := result.Value()\n-- use the non-error value here\n```\n\n### Custom Data Types\n\nYou may define a custom data type, which are custom structures which you may mix with other structures. Note that this is more like a mixin pattern than inheritance.\n\n```haskell\ndata BaseNode {\n\tid     = ''\n\tparent = empty(BaseNode) -- returns a Maybe\u003cBaseNode\u003e(empty_error)\n\n\t-- methods MUST have a `this` variable as first argument\n\tfn String(this) {\n\t\treturn id\n\t}\n}\n\ndata NumberNode(BaseNode) {\n\tvalue = 0\n\n\tfn String(this) {\n\t\treturn sprintf('\u003c%s, %d\u003e', BaseNode.String(this), this.value)\n\t}\n}\n\nnumber := NumberNode { id='xyz', value=5 }\nnumber.String() -- '\u003cxyz, 5\u003e'\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenatopp%2Fpipelang","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frenatopp%2Fpipelang","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenatopp%2Fpipelang/lists"}