{"id":16662745,"url":"https://github.com/gilch/hebigo","last_synced_at":"2025-03-21T17:32:08.587Z","repository":{"id":47154343,"uuid":"197118676","full_name":"gilch/hebigo","owner":"gilch","description":"蛇語(HEH-bee-go): An indentation-based skin for Hissp.","archived":false,"fork":false,"pushed_at":"2023-04-19T04:21:37.000Z","size":187,"stargazers_count":24,"open_issues_count":11,"forks_count":3,"subscribers_count":8,"default_branch":"prototype","last_synced_at":"2024-10-13T10:38:42.698Z","etag":null,"topics":["hebigo","hissp","hotword","indentation","lisp","macro","metaprogramming","python","transpiler"],"latest_commit_sha":null,"homepage":"https://github.com/gilch/hissp","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gilch.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":"2019-07-16T04:11:06.000Z","updated_at":"2024-08-03T06:45:26.000Z","dependencies_parsed_at":"2023-01-17T20:55:40.699Z","dependency_job_id":null,"html_url":"https://github.com/gilch/hebigo","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/gilch%2Fhebigo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gilch%2Fhebigo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gilch%2Fhebigo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gilch%2Fhebigo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gilch","download_url":"https://codeload.github.com/gilch/hebigo/tar.gz/refs/heads/prototype","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221817217,"owners_count":16885478,"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":["hebigo","hissp","hotword","indentation","lisp","macro","metaprogramming","python","transpiler"],"created_at":"2024-10-12T10:38:47.530Z","updated_at":"2024-10-28T10:31:36.494Z","avatar_url":"https://github.com/gilch.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Gitter](https://badges.gitter.im/hissp-lang/community.svg)](https://gitter.im/hissp-lang/community?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge)\n# Hebigo\n蛇語(HEH-bee-go): Snake-speak.\nHebigo is an indentation-based [Hissp](https://github.com/gilch/hissp) skin designed to resemble Python.\n\nIt includes the Hebigo Hissp reader, the Jupyter-console based Hebigo REPL,\nand the Hebigo basic macros—a collection of Python-like compiler macros,\nwhich also function independently of the Hebigo reader\n(i.e. they work in Lissp or Hissp readerless mode as well).\n\nHebigo is still in the prototyping phase, so it's not on PyPI yet.\nInstall it directly from GitHub with\n```\npip install git+https://github.com/gilch/hebigo\n```\nSee the native tests for example Hebigo code.\n\nHebigo keeps Python's expressions as *bracketed expressions*,\nbut completely replaces Python's *statements* with *hotword expressions*,\nwhich have Hissp's literals, semantics, and macros.\n\n## Bracketed Expressions\nBracketed expression are called that because they must be \"bracketed\"\nsomehow in order to be distinguishable from the hotword expressions.\nParentheses will always work, but `[]` or `{}` are sufficient.\nQuotation marks also work, even with prefixes, like `b''` or `f\"\"\"\"\"\"`, etc.\n\nBracketed expressions are mainly used for infix operators, simple literals, and f-strings\n(things that might be awkward as hotword expressions),\nbut any Python expression will work,\neven more complex ones like nested comprehensions or chained method calls.\nIt's best to keep these simple though.\nYou can't use macros in them.\n\n## Hotword Expressions\nHotword expressions are called expressions because they evaluate to a value,\nbut they resemble Python's statements in form:\n```\nword:\n   block1\n   subword:\n       subblock\n   block2\n```\netc.\n\nThe rules are as follows.\n\n1. A word ending in a `:` is a \"hotword\", that is, a function or macro invocation that can take arguments.\n```\nhotword: not_hotword\n```\n\n2. A hotword with no whitespace after its colon is *unary*. Otherwise it's *multiary*.\n```\nunary:arg\nmultiary0:\nmultiary1: arg\nmultiary2: a b\nmultiary3: a b c\n```\n\n3. Multiary hotwords take all remaning arguments in a line.\n```\nhotword: arg1 arg2 arg3: a:0 b: 1 2\n```\nParsed like\n```\nhotword(arg1, arg2, arg3(a(0), b(1, 2)))\n```\n\n4. The first (multiary) hotword of the line gets the arguments in the indented block for that line (if any).\n```\nmultiary: a b c\n    d e f\nfoo unary:gets_block: gets_line: 1 2\n    a b\n    c d\n```\nParsed like\n```\nmultiary(a, b, c, d, e, f)\nfoo\nunary(gets_block(gets_line(1, 2), a, b, c, d))\n```\nAnother way to think of it is that a unary applied to another hotword creates a *compound hotword*, which is a composition of the functions.\nIn the example above, `foo` is not a hotword (no colon),\nand the compound hotword `unary:gets_block:` is the first hotword of the line,\nso it gets the indented block below the line.\n\n5. The special hotword `pass:` invokes its first argument, passing it the remainder.\nThis allows you to invoke things that are not words, like lambda expressions:\n```\npass: foo a b\npass: (lambda *a: a) 1 2 3\n```\nParsed like\n```\nfoo(a, b)\n(lambda *a: a)(1, 2, 3)\n```\n### Style\nThese indentation rules were designed to resemble Python and make editing easier with a basic editor than for S-expressions.\nAs a matter of style, arguments should be passed in one of three forms, which should not be mixed for function calls.\n```\nlinear: a b c d\nlinear_block:\n    a b c d\nblock:\n    a\n    b\n    c\n    d\n# What NOT to do, although it compiles fine.\nbad_mix: a\n   b c\n   d\n```\ncompare that to the same layout for Python invocations.\n```\nlinear(a, b, c, d)\nlinear_block(\n    a, b, c, d\n)\nblock(\n    a,\n    b,\n    c,\n    d,\n)\n# What NOT to do.\nbad_mix(a,\n    b, c\n    d\n)  # PEP 8 that. Please.\n```\nThe above is for function calls only.\nMacro invocations are not exactly bound by these three layout styles,\nand may instead have other documented preferred layouts.\n\nYou should group arguments using whitespace when it makes sense to do so.\nAnywhere you'd use a comma (or newline) in Clojure, you add an extra space or newline.\nThis usually after the `:` in function invocations or parameter tuples,\nwhere the arguments are implicitly paired.\n```\nlinear: x : a b  c d  # Note extra space between b and c.\nlinear_block:\n    x : a b  c d\nblock:\n    x\n    : a b  # Newline also works.\n    c d\n```\n### Literals\nLiterals are mostly the same as Lissp for hotword expressions\n(and exactly like Python in bracketed expressions).\n\nHebigo does not munge symbols like Lissp does.\nQualified symbols (like ``builtins..print``) are allowed,\nbut not in bracketed expressions, which must be pure Python.\n\n*Control words* are words that start with a `:`.\nThese are not allowed in bracketed expressions either\n(although they're just compiled to strings, which are).\nYou'll need these for paired arguments, same as Lissp.\nThese two expressions are normally equivalent in Hebigo.\n```\nprint: 1 2 3 : :* 'abc'  sep \"/\"  # Hotword expression.\n(print(1, 2, 3, *'abc', sep=\"/\"))  # Bracketed expression.\n```\nHowever, if a macro named `print` were defined,\nthen the hotword version would invoke the macro,\nbut the bracketed version would still invoke the builtin,\nbecause macros can only be invoked in hotword expressions.\n\nControl words may also be used as hotwords,\nin which case they both begin and end with a colon.\nThis makes no sense at the top level (because strings are not callable),\nbut macros do use them to group arguments.\n\nUnlike Lissp, normal string literals cannot contain literal newlines.\nUse `\\n` or triple quotes like Python instead.\n(Recall that strings count as bracketed expressions.)\n\nHotword expressions may contain bracketed expressions,\nbut not the reverse, since bracketed expressions must be valid Python,\njust like how the statements that the hotword expressions replace may contain expressions,\nbut Python expressions may not contain Python statements.\n\nAnd finally, the `!` is an abbreviation for `hebi.basic.._macro_.`,\nthe qualifier for Hebigo's included macros.\n(This can't work in bracketed expressions either.)\nHebigo has no other \"reader macros\".\n\n## Examples\n\n(Also see Hebigo's native tests.)\n\n### Obligatory factorial example.\n\nIn basic Lissp. (Prelude assumed.)\n```racket\n(define factorial\n  (lambda n\n    (if-else (eq n 0)\n      1\n      (mul n (factorial (sub n 1))))))\n```\nLiteral translation of the above to Hebigo.\n```python\ndefine: factorial\n  lambda: n\n    ifQz_else: eq: n 0\n      1\n      mul: n factorial: sub: n 1\n```\nNote the munged name.\n\nIn more idiomatic Hebigo with statement macros and bracketed expressions.\n```python\ndef: factorial: n\n  if: (n == 0)\n    :then: 1\n    :else: (n * factorial(n - 1))\n```\nLiteral translation of the above to Lissp. (Statement macros required.)\n```racket\n(def_ (factorial n)\n  (if_ .#\"n == 0\"\n    (:then 1)\n    (:else .#\"n * factorial(n - 1)\")))\n```\nNote the injections.\n\nFinally, in idiomatic Lissp with Hebigo's macros.\n```racket\n(def_ (factorial n)\n  (if-else (eq n 0)\n    1\n    (mul n (factorial (sub n 1)))))\n```\n\n### Fibonacci\n\nIn Python.\n```python\nfrom functools import lru_cache\n\n@lru_cache(None)\ndef fibonacci(n):\n    if n \u003c= 1:\n        return n\n    return fibonacci(n - 1) + fibonacci(n - 2)\n```\nIn Hebigo.\n```python\ndef: fibonacci: n\n  :@ functools..lru_cache: None  # Qualified identifier in decorator.\n  if: (n \u003c= 1)\n    :then: n\n    :else: (fibonacci(n - 1) + fibonacci(n - 2))\n```\nLiteral translation to Lissp.\n```racket\n(def_ (fibonacci n)\n  :@ (functools..lru_cache None) ; Qualified identifier in decorator.\n  (if_ .#\"n \u003c= 1\"\n    (:then n)\n    (:else .#\"fibonacci(n - 1) + fibonacci(n - 2)\")))\n```\nIn basic Lissp.\n```racket\n(define fibonacci\n  ((functools..lru_cache None) ; Callable expression.\n   (lambda n\n     (if-else (le n 1)\n       n\n       (add (fibonacci (sub n 1))\n            (fibonacci (sub n 2)))))))\n```\nLiteral translation to Hebigo\n```python\ndefine: fibonacci\n  pass: functools..lru_cache: None  # Callable expression.\n    lambda: n\n      ifQz_else: le: n 1\n        n\n        add:\n          fibonacci: sub: n 1\n          fibonacci: sub: n 2\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgilch%2Fhebigo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgilch%2Fhebigo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgilch%2Fhebigo/lists"}