{"id":558,"date":"2017-07-07T10:18:44","date_gmt":"2017-07-07T10:18:44","guid":{"rendered":"http:\/\/www.rangakrish.com\/?p=558"},"modified":"2017-07-07T13:54:10","modified_gmt":"2017-07-07T13:54:10","slug":"clpython-python-in-common-lisp","status":"publish","type":"post","link":"https:\/\/www.rangakrish.com\/index.php\/2017\/07\/07\/clpython-python-in-common-lisp\/","title":{"rendered":"CLPython &#8211; Python in Common Lisp"},"content":{"rendered":"<p>My work in the area of NLP requires\u00a0me to work with several frameworks across multiple languages such as Java, Python and Lisp. Sometime ago I got a chance to experiment with <em><strong><a href=\"https:\/\/common-lisp.net\/project\/clpython\/\" target=\"_blank\">CLPython<\/a><\/strong><\/em>, an open-source implementation of Python in Common Lisp. Although CLPython is not under active development now, I found it quite usable. In fact it worked pretty well with both <a href=\"https:\/\/franz.com\/products\/allegrocl\/\" target=\"_blank\"><em><strong>Allegro CL<\/strong><\/em><\/a> and <a href=\"http:\/\/www.lispworks.com\" target=\"_blank\"><em><strong>LispWorks<\/strong><\/em><\/a>.<\/p>\n<p>In today&#8217;s post, I would like to\u00a0show some examples of this implementation.<\/p>\n<p>You can install CLPython through <a href=\"https:\/\/www.quicklisp.org\/beta\/\" target=\"_blank\"><em><strong>Quicklisp<\/strong><\/em><\/a>:<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><b>(ql:quickload &#8220;clpython&#8221;)<\/b><\/span><\/p>\n<p>For convenience, I created a package and imported symbols from this and standard packages.<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><b>(defpackage :pytest<\/b><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><b>\u00a0 (:use :cl :clos :clpython))<\/b><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><b>(in-package :pytest)<\/b><\/span><\/p>\n<p>The first thing I did was to create a <em><strong>habitat<\/strong><\/em>\u00a0&#8211; a runtime environment within which expression values are saved across Python calls. Although this is strictly not necessary, I felt that the interaction would\u00a0be a bit tedious\u00a0without it.<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>(setf *habitat* (make-habitat))<\/strong><\/span><\/p>\n<p>We are all set now. We\u00a0can execute any Python code by enclosing it in double quotes and passing it to the Lisp function <em><strong>run<\/strong><\/em>. The following function assigns to a variable and modifies it:<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>(defun test1 ()<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>\u00a0 (run &#8220;x = 100&#8221;)<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>\u00a0 (run &#8220;x = x + 200&#8221;))<\/strong><\/span><\/p>\n<p>This is what you get when you run this function:<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>PYTEST 4 &gt; (test1)<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>300<\/strong><\/span><\/p>\n<p>The answer is as expected. Note that if we had not initialized the default <em><strong>habitat<\/strong><\/em>, the variable <em><strong>x<\/strong><\/em> would not have been shared across the two different <em><strong>run<\/strong><\/em> statements. The sharing happens through the <em><strong>habitat<\/strong><\/em>.<\/p>\n<p>OK. Let us define a Python function dynamically.<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>(defun test2 (k)<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>\u00a0 (run\u00a0<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>\u00a0\u00a0 (format nil<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>\u00a0\u00a0 &#8220;def myfun (arg):<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>\u00a0 \u00a0 \u00a0 \u00a0 return arg * ~d&#8221; k)<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>\u00a0\u00a0 ))<\/strong><\/span><\/p>\n<p>The interesting thing about the above Lisp function is that it creates a Python function to make use of the argument supplied to it. So, for instance, the following call:<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>PYTEST 30 &gt; (test2 50)<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>#&lt;python-function myfun (interpreted) (__main__\/myfun) 4030001CA4&gt;<\/strong><\/span><\/p>\n<p>actually defines the following Python function:<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>def myfun(arg):<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>\u00a0 \u00a0 \u00a0 return arg * 50<\/strong><\/span><\/p>\n<p>That is, the argument supplied to <em><strong>test2<\/strong><\/em> is embedded in the generated Python function!<\/p>\n<p>The other neat thing is that we can call the generated Python function as if it is a Lisp function!<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>PYTEST 31 &gt; (funcall (test2 50) 25)<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>1250<\/strong><\/span><\/p>\n<p>Isn&#8217;t that interesting?<\/p>\n<p>You can do the same thing on a Python <em><strong>lambda<\/strong><\/em> too.<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>PYTEST 32 &gt; (funcall (run &#8220;lambda x: x * x&#8221;) 50)<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>2500<\/strong><\/span><\/p>\n<p>What sbout Python functions that return multiple values? CLPython makes the result available as a <em><strong>list<\/strong><\/em>. Consider this example:<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>(defun test4 ()<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>\u00a0 (run\u00a0<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>\u00a0\u00a0 &#8220;def myfun ():<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>\u00a0 \u00a0 \u00a0 \u00a0 return 10, 20, 30&#8243;))<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>PYTEST 14 &gt; (setf fn (test4))<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>#&lt;python-function myfun (interpreted) (__main__\/myfun) 4030000F14&gt;<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>PYTEST 15 &gt; (funcall fn)<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>(10 20 30)<\/strong><\/span><\/p>\n<p>Python lists can be accessed as <em><strong>vectors<\/strong><\/em> in Lisp.<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>PYTEST 33 &gt; (setf res (run &#8220;[1, 2, 3, 4]&#8221;))<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>#(1 2 3 4)<\/strong><\/span><\/p>\n<p>We can use <em><strong>aref<\/strong><\/em> to access the individual elements of the vector.<\/p>\n<p>The last feature we will look at is Python <em><strong>Dictionary<\/strong><\/em>.<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>PYTEST 34 &gt; (setf table (run &#8220;dict = {&#8216;a&#8217;: 30, &#8216;b&#8217;: 40}&#8221;))<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>#&lt;PY-==-&gt;LISP-VAL Hash Table{2} 4020088B1B&gt;<\/strong><\/span><\/p>\n<p>As you would have guessed, CLPython converts this to a <em><strong>hashtable<\/strong><\/em> in Lisp. This means we can access the Python\u00a0<em><strong>dictionary<\/strong><\/em> elements as <em><strong>hashtable<\/strong><\/em>\u00a0elements in Lisp.<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>PYTEST 7 &gt; (setf (gethash &#8220;b&#8221; table) 60)<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>60<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>PYTEST 8 &gt; (run &#8220;print dict&#8221;)<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>{&#8216;a&#8217;: 30, &#8216;b&#8217;: 60}<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>PYTEST 9 &gt; (setf (gethash &#8220;c&#8221; table) 123)<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>123<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>PYTEST 10 &gt; (run &#8220;print dict&#8221;)<\/strong><\/span><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>{&#8216;a&#8217;: 30, &#8216;b&#8217;: 60, &#8216;c&#8217;: 123}<\/strong><\/span><\/p>\n<p>Not only are we able to modify the values in the dictionary, but we can also insert new elements!<\/p>\n<p>That is it for today&#8217;s post. Hope you enjoyed it.<\/p>\n<p><strong>Have a great day!<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>My work in the area of NLP requires\u00a0me to work with several frameworks across multiple languages such as Java, Python and Lisp. Sometime ago I got a chance to experiment with CLPython, an open-source implementation of Python in Common Lisp. Although CLPython is not under active development now, I found it quite usable. In fact [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[18,103],"tags":[104,19],"class_list":["post-558","post","type-post","status-publish","format-standard","hentry","category-lisp","category-python","tag-clpython","tag-lisp"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9OLnF-90","jetpack-related-posts":[{"id":567,"url":"https:\/\/www.rangakrish.com\/index.php\/2017\/07\/22\/clpython-python-in-common-lisp-part-2\/","url_meta":{"origin":558,"position":0},"title":"CLPython: Python in Common Lisp &#8211; Part 2","author":"admin","date":"July 22, 2017","format":false,"excerpt":"We looked at the basic features of CLPython\u00a0in our last blog. In today's post let us look at the support for Python classes. PYTEST 130 > (defun pyclass () \u00a0 (run\u00a0 \"class Employee: \u00a0\u00a0 def __init__(self, name, dept): \u00a0\u00a0 \u00a0 self.name = name \u00a0\u00a0 \u00a0 self.dept = dept \u00a0\u00a0 def\u2026","rel":"","context":"In &quot;LISP&quot;","block_context":{"text":"LISP","link":"https:\/\/www.rangakrish.com\/index.php\/category\/lisp\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3312,"url":"https:\/\/www.rangakrish.com\/index.php\/2024\/01\/28\/the-hy-programming-language\/","url_meta":{"origin":558,"position":1},"title":"The Hy Programming Language","author":"admin","date":"January 28, 2024","format":false,"excerpt":"In an earlier article\u00a0I had explained how to execute Python code from within Common Lisp using \u201cCLPython\u201d package. In contrast to that approach, \u201cHy\u201d\u00a0is a Lisp-style language (not compatible with Common Lisp) that is embedded in Python and hence provides seamless interoperability with Python code. Installation is straightforward (it is\u2026","rel":"","context":"In &quot;Hy Language&quot;","block_context":{"text":"Hy Language","link":"https:\/\/www.rangakrish.com\/index.php\/category\/hy-language\/"},"img":{"alt_text":"Hy REPL","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2024\/01\/console-300x148.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":3199,"url":"https:\/\/www.rangakrish.com\/index.php\/2023\/09\/04\/simulating-python-zip-in-lisp\/","url_meta":{"origin":558,"position":2},"title":"Simulating Python Zip in Lisp","author":"admin","date":"September 4, 2023","format":false,"excerpt":"The zip() function in Python is a convenient mechanism for iterating over multiple \u201citerables\u201d in parallel. Looping over lists is a common scenario. Here is the output generated by the above code: Common Lisp does not have such a feature built into the language or as part of the standard\u2026","rel":"","context":"In &quot;LISP&quot;","block_context":{"text":"LISP","link":"https:\/\/www.rangakrish.com\/index.php\/category\/lisp\/"},"img":{"alt_text":"Python Zip() Feature","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2023\/09\/python-code-300x99.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":2200,"url":"https:\/\/www.rangakrish.com\/index.php\/2020\/11\/08\/book-review-the-common-lisp-condition-system-beyond-exception-handling-with-control-flow-mechanisms\/","url_meta":{"origin":558,"position":3},"title":"Book Review &#8211; The Common Lisp Condition System: Beyond Exception Handling with Control Flow Mechanisms.","author":"admin","date":"November 8, 2020","format":false,"excerpt":"Title: The Common Lisp Condition System: Beyond Exception Handling with Control Flow Mechanisms Author: Micha\u0142 \"phoe\" Herda Publisher: Apress Year: 2020 Unlike with other languages, it is rare to find new books being published on Lisp. The last book on Lisp, which I purchased was \u201cCommon Lisp Recipes\u201d\u00a0\u00a0by Edmund Weitz\u2026","rel":"","context":"In &quot;Book Review&quot;","block_context":{"text":"Book Review","link":"https:\/\/www.rangakrish.com\/index.php\/category\/book-review\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2020\/11\/Cover-page-209x300.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":2927,"url":"https:\/\/www.rangakrish.com\/index.php\/2022\/10\/20\/why-learn-lisp\/","url_meta":{"origin":558,"position":4},"title":"Why Learn Lisp?","author":"admin","date":"October 20, 2022","format":false,"excerpt":"In the last article, I had shared my views on why programmers should learn Prolog, preferably as the first language. What language should one learn next? I strongly pitch for Lisp, to be precise, \u201cCommon Lisp\u201d. Lisp happens to be the second oldest (1958) programming language, only after Fortran (1957)!\u2026","rel":"","context":"In &quot;LISP&quot;","block_context":{"text":"LISP","link":"https:\/\/www.rangakrish.com\/index.php\/category\/lisp\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2645,"url":"https:\/\/www.rangakrish.com\/index.php\/2021\/12\/25\/calling-lisp-functions-from-d-language\/","url_meta":{"origin":558,"position":5},"title":"Calling Lisp Functions from D Language","author":"admin","date":"December 25, 2021","format":false,"excerpt":"After exploring \"newLisp\" in the past few posts, I would like to start looking at the \"D Programming Language\"\u00a0(DLang). DLang\u00a0has been around since 2001. It was originally created by Walter Bright and later Andrei Alexandrescu joined the team in 2007. The main inspiration for DLang was C++, although it uses\u2026","rel":"","context":"In &quot;D Language&quot;","block_context":{"text":"D Language","link":"https:\/\/www.rangakrish.com\/index.php\/category\/d-language\/"},"img":{"alt_text":"Lisp Function Called from D","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2021\/12\/Lisp-300x107.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2021\/12\/Lisp-300x107.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2021\/12\/Lisp-300x107.jpg?resize=525%2C300&ssl=1 1.5x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/posts\/558","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/comments?post=558"}],"version-history":[{"count":0,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/posts\/558\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/media?parent=558"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/categories?post=558"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/tags?post=558"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}