{"id":25044710,"url":"https://github.com/blad/lain","last_synced_at":"2025-09-03T13:40:49.491Z","repository":{"id":74933685,"uuid":"292581735","full_name":"blad/Lain","owner":"blad","description":"Lain: A Minimal Lisp Dialect","archived":false,"fork":false,"pushed_at":"2020-09-04T00:30:18.000Z","size":9789,"stargazers_count":10,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-21T02:05:22.762Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/blad.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"zenodo":null}},"created_at":"2020-09-03T13:42:40.000Z","updated_at":"2025-02-13T06:40:03.000Z","dependencies_parsed_at":"2023-07-11T14:47:04.252Z","dependency_job_id":null,"html_url":"https://github.com/blad/Lain","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/blad/Lain","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blad%2FLain","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blad%2FLain/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blad%2FLain/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blad%2FLain/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/blad","download_url":"https://codeload.github.com/blad/Lain/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blad%2FLain/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273453492,"owners_count":25108470,"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","status":"online","status_checked_at":"2025-09-03T02:00:09.631Z","response_time":76,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2025-02-06T05:19:05.041Z","updated_at":"2025-09-03T13:40:49.483Z","avatar_url":"https://github.com/blad.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"Lain\n---------------\n\nLain is a lisp dialect used within [Ronin, an experimental graphics \nterminal][ronin]. This guide explains the Lain language. Lain does not have a \nstandard library by default so there are many basic operations that can not be \ndone without defining some basic operations as part of the run time \nenvironment. However, this also gives flexibility to any program that uses Lain \nto include standard library functions that are fit for their task.\n\nThe primary characteristic of lisp, and this Lain, is that it's syntax is based \non s-expressions. S-Expressions are characterized by their heavy use of \nparenthesis, and represent data or code. An s-expression can be an atom, or \nanother s-expression. This gives us a program where logic is typically deeply \nparetherized.\n\nExamples of atoms, are values or names that can not be broken down further. For \nexample: `10`, `name`, and `\"Hello World\"` are considered atoms. Atoms can then \nbe constructed into lists by parentherizing multiple atoms together, such as \n`(1 2 3 4)` and `(\"a\" \"b\" \"c\")`, which are lists of values. However within \nLain, lists can also represent function calls, where the first item in the list \nis the function name followed by all the function's arguments.\n\nLain gives us the following features as part of the core language:\n\n- Binding values to names\n- Defining named functions\n- Defining lambda functions (anonymous functions)\n- Binding multiple values to names using `let`\n- Conditional expressions via `if`\n- Defining lists\n- Defining objects/dictionaries and accessing values via a key\n- Primatives include: strings, numbers, booleans, and symbols.\n\n## About Lists\n\nLists are core to Lain, in most instances anything wrapped in parenthesis will \nbe treated as a list. The two exceptions are when a list's first item is a \nfunction name or a keyword.\n\nWhen a function name is encountered, the function is evaluated with the \nremaining list items as the function's arguments.\n\nWhen a keyword is encountered, the remaining list items are treated accoding to \nthe keyword's pre-defined behaviour. In some instances subsequent list items \nare expected in a specific order, or evaluated by rules defined for the \nkeyword. Below those behaviours are defined for: `def`, `defn`, `λ`, `let`, \n`if` and property accessors.\n\n## Binding Values to Names (Variables)\n\nVariables are names that map to a value.\n\nThe value of a variable can be a primitive, list, or result of a function.\n\n```\n;; A primitive value:\n(def game-name \"pong\")\n(def ball-speed 100)\n(def friction 0.1)\n(def game-over false)\n\n;; A list:\n(def levels (1 2 3))\n\n;; Result of a function call:\n(def player-position (position 0 0))\n(def difficulty (double 1))\n```\n\n## Creating Named Functions\n\n\n```\n; Return the first argument\n(defn identity (value) value)\n\n; Wrap the first argument in a list\n(defn short-list (value) (value))\n\n; Wrap two arguments in a list\n(defn pair (a b) (a b))\n\n; Get the first element of the list\n(defn first (xs) (:0 xs))\n\n; Get the second element of the list\n(defn second (xs) (:1 xs))\n```\n\n\n## Lambda Functions\n\nLambda functions are function that do not have a name...this is useful when a \nfunction expects a function as parameter, but we'd prefer to define the \nfunction in line.\n\n```\n; Identity lambda function\n(λ (value) value)\n\n; Wrap the first argument in a list\n(λ (value) (value))\n\n; Wrap two arguments in a list\n(λ (a b) (a b))\n```\n\nLambda functions can also be used in conjunction with variable definitions to \ngive them a name.\n\nWhile this is less common, there are times when it may be convenient to do this.\n\n```\n(def identity (λ (value) value))\n```\n\n## Binding Values Using `let`\n\n`let` is a keyword that allows us to bind multiple values to names as a single \nexpression. This is most useful inside of function bodies when there is need to \ncalculate intermediate values.\n\nThe syntax has 3 parts, the `let` keyword, followed by a list of key-value \npairs for the bindings, and lastly the return atom or s-expression.\n\n`(let {list of pairs} {expression value})`\n\nAn example of a standalone `let` is:\n\n```\n; Bind values to x and y, use them to calculate total\n; return total.\n(let \n  (\n    (x 1) \n    (y 2) \n    (total (add x y)))\n  total)\n```\n\n## Conditional Expressions Using `if`\n\n`if` is another keyword that allows us to conditionally evaluate one of two \ns-expressions given a condition is met.\n\nThe syntax has 4 parts. The `if` keyword, an expression evaluating to a true or \nfalse, an expression to be evaluated when true, and an expression to be \nevaluated when false.\n\n`(if {condition} {true expression} {optional false expression})`\n\nAn example of a standalone `if` is:\n```\n(if \n  (is-less-than-100 value)\n  (capitalize \"yes!\")\n  (capitalize \"no!\"))\n```\n\n[ronin]: https://github.com/hundredrabbits/Ronin \"Ronin: An Experimental \nGraphics Terminal\"","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblad%2Flain","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblad%2Flain","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblad%2Flain/lists"}