{"id":13803960,"url":"https://github.com/marcoheisig/cl4py","last_synced_at":"2025-04-04T15:45:29.075Z","repository":{"id":46040091,"uuid":"133661775","full_name":"marcoheisig/cl4py","owner":"marcoheisig","description":"Common Lisp for Python","archived":false,"fork":false,"pushed_at":"2024-12-16T13:54:47.000Z","size":109,"stargazers_count":103,"open_issues_count":3,"forks_count":15,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-18T16:58:59.346Z","etag":null,"topics":["common-lisp","python"],"latest_commit_sha":null,"homepage":null,"language":"Python","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/marcoheisig.png","metadata":{"files":{"readme":"README.rst","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":"2018-05-16T12:23:43.000Z","updated_at":"2025-03-18T04:53:44.000Z","dependencies_parsed_at":"2024-05-02T10:06:37.357Z","dependency_job_id":"5e868402-eea4-43c7-9e60-5b267cdfe2d0","html_url":"https://github.com/marcoheisig/cl4py","commit_stats":{"total_commits":113,"total_committers":5,"mean_commits":22.6,"dds":0.1415929203539823,"last_synced_commit":"71107a7b56709c91d476b16e3ec1ad22d453fda6"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcoheisig%2Fcl4py","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcoheisig%2Fcl4py/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcoheisig%2Fcl4py/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcoheisig%2Fcl4py/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcoheisig","download_url":"https://codeload.github.com/marcoheisig/cl4py/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247208066,"owners_count":20901568,"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":["common-lisp","python"],"created_at":"2024-08-04T01:00:39.588Z","updated_at":"2025-04-04T15:45:29.046Z","avatar_url":"https://github.com/marcoheisig.png","language":"Python","funding_links":[],"categories":["Python ##"],"sub_categories":[],"readme":"cl4py - Common Lisp for Python\n==============================\n\nThe library cl4py (pronounce as *clappy*) allows Python programs to call\nCommon Lisp libraries.  Its official mascot is the cl4py-bird:\n\n.. image:: ./cl4py.png\n\nMotivation\n----------\n\nYou are a Python programmer, but you want access to some of the powerful\nfeatures of Lisp, for example to compile code at run time?  Or you want to\nuse some `awesome Lisp libraries \u003chttp://codys.club/awesome-cl/\u003e`_?  Or\nyou are a Lisp programmer and want to show your work to your Python\nfriends.  In all these cases, cl4py is here to help you.\n\nTutorial\n--------\n\nYou can start any number of Lisp subprocesses within Python, like this:\n\n.. code:: python\n\n    \u003e\u003e\u003e import cl4py\n    \u003e\u003e\u003e lisp = cl4py.Lisp()\n\nOf course, this requires you have some Lisp installed. If not, use\nsomething like ``apt install sbcl``, ``pacman -S sbcl`` or ``brew install\nsbcl`` to correct this deficiency.  Once you have a running Lisp process,\nyou can execute Lisp code on it:\n\n.. code:: python\n\n    # In Lisp, numbers evaluate to themselves.\n    \u003e\u003e\u003e lisp.eval( 42 )\n    42\n\n    # ('+', 2, 3) is a short notation for cl4py.List(cl4py.Symbol('+'), 2, 3).\n    # For convenience, whenever a Python tuple is converted to Lisp\n    # data, any strings therein are automatically converted to Lisp symbols.\n    \u003e\u003e\u003e lisp.eval( ('+', 2, 3) )\n    5\n\n    # Nested expressions are allowed, too.\n    \u003e\u003e\u003e lisp.eval( ('/', ('*', 3, 5), 2) )\n    Fraction(15, 2)\n\n    # Use cl4py.List instead of tuples to avoid the automatic conversion of\n    # strings to symbols.\n    \u003e\u003e\u003e lisp.eval( cl4py.List(cl4py.Symbol('STRING='), 'foo', 'bar') )\n    ()\n    \u003e\u003e\u003e lisp.eval( cl4py.List(cl4py.Symbol('STRING='), 'foo', 'foo') )\n    True\n\n    # Here is how you can lookup a symbol's value:\n    \u003e\u003e\u003e lisp.eval(cl4py.Symbol('*PRINT-BASE*', 'COMMON-LISP'))\n    10\n\n    # Of course you can also use Lisp macros:\n    \u003e\u003e\u003e lisp.eval( ('loop', 'for', 'i', 'below', 5, 'collect', 'i') )\n    List(0, 1, 2, 3, 4)\n\n    \u003e\u003e\u003e lisp.eval( ('with-output-to-string', ('stream',),\n                      ('princ', 12, 'stream'),\n                      ('princ', 34, 'stream')) )\n    '1234'\n\nA cl4py.Lisp object not only provides ``eval``, but also methods for\nlooking up functions and packages:\n\n.. code:: python\n\n    \u003e\u003e\u003e add = lisp.function('+')\n    \u003e\u003e\u003e add(1, 2, 3, 4)\n    10\n\n    \u003e\u003e\u003e div = lisp.function('/')\n    \u003e\u003e\u003e div(2, 4)\n    Fraction(1, 2)\n\n    # Lisp packages are automatically converted to Python modules.\n    \u003e\u003e\u003e cl = lisp.find_package('CL')\n    \u003e\u003e\u003e cl.oddp(5)\n    True\n\n    \u003e\u003e\u003e cl.cons(5, None)\n    List(5)\n\n    \u003e\u003e\u003e cl.remove(5, [1, -5, 2, 7, 5, 9], key=cl.abs)\n    [1, 2, 7, 9]\n\n    # Higher-order functions work, too!\n    \u003e\u003e\u003e cl.mapcar(cl.constantly(4), (1, 2, 3))\n    List(4, 4, 4)\n\n    # cl4py even supports macros and special forms as a thin\n    # wrapper around lisp.eval.\n    \u003e\u003e\u003e cl.loop('repeat', 5, 'collect', 42)\n    List(42, 42, 42, 42, 42)\n\n    \u003e\u003e\u003e cl.progn(5, 6, 7, ('+', 4, 4))\n    8\n\nWhen converting Common Lisp packages to Python modules, we run into the\nproblem that not every Common Lisp symbol name is a valid Python\nidentifier.  As a remedy, so we attempt to substitute problematic\ncharacters and symbols with something that Python can digest.  Here you can\nsee this substitution rules in action:\n\n.. code:: python\n\n    # hyphens are turned into underscores\n    \u003e\u003e\u003e cl.type_of(\"foo\")\n    List(Symbol(\"SIMPLE-ARRAY\", \"COMMON-LISP\"), Symbol(\"CHARACTER\", \"COMMON-LISP\"), List(3))\n\n    # The functions +, -, *, /, 1+, and 1- are renamed to add, sub,\n    # mul, div, inc, and dec, respectively.\n    \u003e\u003e\u003e cl.add(2,3,4,5)\n    14\n\n    # Within a string, occurrences of -, *, +, \u003c=, \u003c, =, /=, \u003e=, gt, and ~,\n    # are replaced by _, O, X, le, lt, sim, ne, ge, ge, gt, and tilde, respectively.\n    \u003e\u003e\u003e cl.stringgt('baz', 'bar')\n    2\n\n    # Earmuffs are stripped\n    \u003e\u003e\u003e cl.print_base\n    10\n\n    # Constants are capitalized\n    \u003e\u003e\u003e cl.MOST_POSITIVE_DOUBLE_FLOAT\n    1.7976931348623157e+308\n\nThe cl4py module provides a Cons class that mimics cons cells in Lisp.\n\n.. code:: python\n\n    \u003e\u003e\u003e lisp.eval( ('CONS', 1, 2) )\n    Cons(1, 2)\n\n    \u003e\u003e\u003e lst = lisp.eval( ('CONS', 1, ('CONS', 2, () )) )\n    List(1, 2)\n    \u003e\u003e\u003e lst.car\n    1\n    \u003e\u003e\u003e lst.cdr\n    List(2) # an abbreviation for Cons(2, ())\n\n    # cl4py Conses are iterable!\n    \u003e\u003e\u003e list(lst)\n    [1, 2]\n    \u003e\u003e\u003e sum(lst)\n    3\n\n    # cl4py also supports dotted and circular lists.\n    \u003e\u003e\u003e lisp.eval( ('CONS', 1, ('CONS', 2, 3 )) )\n    DottedList(1, 2, 3)\n\n    \u003e\u003e\u003e twos = cl.cons(2,2)\n    \u003e\u003e\u003e twos.cdr = twos\n    \u003e\u003e\u003e twos\n    DottedList(2, ...)\n\n    \u003e\u003e\u003e cl.mapcar(lisp.function('+'), (1, 2, 3, 4), twos)\n    List(3, 4, 5, 6)\n\n\nFrequently Asked Problems\n-------------------------\n\nWhy does my Lisp subprocess complain about ``Package QL does not exist``.\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nBy default, cl4py starts a Lisp subprocess with ``sbcl --script``.  This\nmeans, that the Lisp process will ignore any user initialization files,\nincluding the Quicklisp setup.  However, we provide an extra option for\ninstalling and loading Quicklisp automatically: ``quicklisp=True``\n\n\n.. code:: python\n\n    \u003e\u003e\u003e lisp = cl4py.Lisp(quicklisp=True);\n    \u003e\u003e\u003e ql = lisp.find_package('QL')\n    \u003e\u003e\u003e ql.quickload('YOUR-SYSTEM')\n\n\nRelated Projects\n----------------\n\n-  `burgled-batteries \u003chttps://github.com/pinterface/burgled-batteries\u003e`_\n   - A bridge between Python and Lisp. The goal is that Lisp programs can\n   use Python libraries, which is in some sense the opposite of\n   cl4py. Furthermore it relies on the less portable mechanism of FFI\n   calls.\n-  `CLAUDE \u003chttps://www.nicklevine.org/claude/\u003e`_\n   - An earlier attempt to access Lisp libraries from Python. The key\n   difference is that cl4py does not run Lisp directly in the host\n   process. This makes cl4py more portable, but complicates the exchange of\n   data.\n-  `cl-python \u003chttps://github.com/metawilm/cl-python\u003e`_\n   - A much heavier solution than cl4py --- let's simply implement Python\n   in Lisp! An amazing project. However, cl-python cannot access foreign\n   libraries, e.g., NumPy. And people are probably hesitant to migrate away\n   from CPython.\n-  `Hy \u003chttp://docs.hylang.org/en/stable/\u003e`_\n   - Python, but with Lisp syntax. This project is certainly a great way to\n   get started with Lisp. It allows you to study the advantages of Lisp's\n   seemingly weird syntax, without leaving the comfortable Python\n   ecosystem. Once you understand the advantages of Lisp, you will doubly\n   appreciate cl4py for your projects.\n-  `py4cl \u003chttps://github.com/bendudson/py4cl\u003e`_\n   - A library that allows Common Lisp code to access Python libraries.  It\n   is basically the inverse of cl4py.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcoheisig%2Fcl4py","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcoheisig%2Fcl4py","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcoheisig%2Fcl4py/lists"}