{"id":15654994,"url":"https://github.com/healeycodes/golfcart","last_synced_at":"2025-05-01T12:50:56.357Z","repository":{"id":112378122,"uuid":"381683378","full_name":"healeycodes/golfcart","owner":"healeycodes","description":"⛳ A minimal programming language inspired by Ink, JavaScript, and Python.","archived":false,"fork":false,"pushed_at":"2021-07-25T17:57:29.000Z","size":2051,"stargazers_count":25,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-30T21:22:18.891Z","etag":null,"topics":["functional-programming","interpreter","language","programming-language"],"latest_commit_sha":null,"homepage":"","language":"Go","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/healeycodes.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":"2021-06-30T11:46:30.000Z","updated_at":"2024-07-09T09:48:24.000Z","dependencies_parsed_at":"2023-05-14T04:00:10.927Z","dependency_job_id":null,"html_url":"https://github.com/healeycodes/golfcart","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/healeycodes%2Fgolfcart","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/healeycodes%2Fgolfcart/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/healeycodes%2Fgolfcart/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/healeycodes%2Fgolfcart/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/healeycodes","download_url":"https://codeload.github.com/healeycodes/golfcart/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251879117,"owners_count":21658690,"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":["functional-programming","interpreter","language","programming-language"],"created_at":"2024-10-03T12:55:20.622Z","updated_at":"2025-05-01T12:50:56.339Z","avatar_url":"https://github.com/healeycodes.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Go](https://github.com/healeycodes/golfcart/actions/workflows/go.yml/badge.svg)](https://github.com/healeycodes/golfcart/actions/workflows/go.yml)\n\n# ⛳ Golfcart\n\n\u003e My blog post: [Creating the Golfcart Programming Language](https://healeycodes.com/creating-the-golfcart-programming-language/)\n\n\u003cbr\u003e\n\n * [Getting Started](#getting-started)\n * [Scope Rules](#scope-rules)\n * [Usage](#usage)\n * [Building and tests](#building-and-tests)\n * [Contributions](#contributions)\n * [License](#license)\n\nGolfcart is a minimal programming language inspired by Ink, JavaScript, and Python – implemented in Go. It's a toy programming language that I built to use for Advent of Code 2021. Another motivation was to learn how to write an interpreter from scratch.\n\n```javascript\n// Here's the classic interview question FizzBuzz\nfor i = 1; i \u003c 101; i = i + 1 {\n    log(if i % 3 == 0 and i % 5 == 0 {\n       \"FizzBuzz\"\n    } else if i % 3 == 0 {\n       \"Fizz\"\n    } else if i % 5 == 0 {\n       \"Buzz\"\n    } else {\n       str(i)\n    })\n}\n```\n\nGolfcart is a dynamic strongly typed language with support for bools, strings, numbers (float64), lists, dicts, and nil (null). There is full support for closures and functions can alter any variable in a higher scope.\n\n```javascript\ncounter = () =\u003e {\n    n = 0\n    () =\u003e {\n        n = n + 1\n        n\n    }\n}\n\nmy_counter = counter()\nmy_counter() // 1\n\nassert(my_counter(), 2)\n```\n\nFor Golfcart, I began with a desire to design a small programming language that didn't use semi-colons or automatic semicolon insertion. So, no statements, and everything should be an expression that evaluates to a value. For example:\n- `if/else if/else` evaluates to the successful branch\n- A variable declaration evaluates to the value\n- Setting a dict value evaluates to the value\n- A for loop evaluates to the number of times the condition expression succeeded\n\n```javascript\nassert(\n    // This runs five times\n    for i = 0; i \u003c 5; i = i + 1 {}, 5\n)\n```\n\n## Getting Started\n\nA Golfcart program is a series of expressions. Line breaks are optional and there are no semi-colons. The final expression is sent to stdout.\n\n```javascript\na = 1 b = 2 assert(a + b, 3) // A successful assert() evaluates to nil\n```\n\nThere are seven types. A type-check can be performed with `type()`.\n\n```javascript\n// Bools\ntrue or false\ntrue and true\n\n// Numbers\n1\n1.1 + 1.1 // 2.2\n\n// Strings\n\"multi-line\nstring\"\n\"1\" + \"2\" // \"12\"\n\n// Lists\n[1, 2]\nnums = [3, 4]\nnums.append(5) // [3, 4, 5]\n[0] + [1] // [0, 1]\n\n// Dicts\n{a: 1} // Accessed by `.a` or `[\"a\"]` like JavaScript\n{b: n =\u003e n + 1} // Values can be any type\nkeys({a: 1}) // [\"a\"]\n\n// Functions\n_ =\u003e nil // All user-defined functions are anonymous, assignable by variable\nn =\u003e n + 1\nsum = (x, y) =\u003e x + y\n\n// Nil\nnil\nnil == nil // true\n```\n\nThe Fibonacci sequence.\n\n```javascript\n// Naive\nt = time()\nfib = n =\u003e if n == 0 {\n    0\n} else if n == 1 {\n    1\n} else {\n    fib(n - 1) + fib(n - 2)\n}\nfib(20)\nlog(\"fib: \" + str(time() - t))\n\n// With memoization \nt = time()\ncache = {\"0\": 0, \"1\": 1}\nfib_memo = n =\u003e if cache[n] != nil {\n    cache[n]\n} else {\n    cache[n] = fib_memo(n - 1) + fib_memo(n - 2)\n}\nfib_memo(20)\nlog(\"fib_memo: \" + str(time() - t))\n```\n\nFor more detailed examples, see:\n- [Example programs](https://github.com/healeycodes/golfcart/tree/main/example%20programs)\n- [Specification programs](https://github.com/healeycodes/golfcart/tree/main/example%20programs/spec%20programs)\n- [Programs that purposefully throw errors](https://github.com/healeycodes/golfcart/tree/main/example%20programs/error%20programs)\n\n(All the above are used as part of Golfcart's test suite)\n\n## Scope Rules\n\nLet's talk about stack frames in Golfcart. A stack frame is a map of variables in scope. It's a recursive structure, every stack frame has a parent apart from the global frame. All functions are anonymous and create closures. Any variable referenced in a higher scope can be altered. Examples explain this better than words.\n\n```javascript\na = 1\na_function = () =\u003e a = 2 // Closure created\na_function() // When called, `a` is changed\na // 2\n\nif true {\n    // `b` is not defined in a higher scope\n    // So, `b` is declared only within this scope\n    b = 3\n}\nb // Error: cannot find value for key 'b'\n\nc = nil\nif true {\n    // This assignment recursively looks in higher scopes for `c`\n    // it's found and that value is altered\n    c = 4\n}\nc // 4\n```\n\n## Usage\n\nPass a Golfcart program as the first command-line argument\n\n```bash\n$ ./golfcart-linux program.golf\n```\n\nRun the binary with no command-line arguments to open the REPL.\n\n```bash\n$ ./golfcart-linux \n\n      .-::\":-.\n    .'''..''..'.\n   /..''..''..''\\\n  ;'..''..''..''.;\n  ;'..''..''..'..;\n   \\..''..''..''/\n    '.''..''...'\n      '-..::-' Golfcart v0.1\nλ \n```\n\nUse `-ebnf` to print the Extended Backus–Naur form grammar to stdout and quit.\n\nUse `-version` to print the version to stdout and quit.\n\n## Building and tests\n\nCreate releases.\n\n```bash\n./build.sh\n```\n\nRun all tests (they also run via GitHub Action on commit).\n\n```bash\ngo test ./...\n```\n\n## Contributions\n\nMore than welcome! Raise an issue with a bug report/feature proposal and let's chat.\n\n## License\n\nMIT.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhealeycodes%2Fgolfcart","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhealeycodes%2Fgolfcart","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhealeycodes%2Fgolfcart/lists"}