Lisp y scheme embebidos
Hablar de Lisp y de Scheme es hablar de dos dialectos del mismo
lenguaje. Un lenguaje que necesita media tarde para aprender su
sintaxis y media vida para aprender realmente a usarlo; aunque,
afortunadamente, rinde desde el minuto uno. En este artículo voy a
hablar de dos dialectos diseñados para ser embebidos en programas,
aplicaciones y sistemas más grandes. Si estás buscando un lenguaje
para dotar a tu sistema de mecanismos para programarle extensiones,
deberías valorar alguno de estos dialectos. Aplicaciones como AutoCAD
(AutoLisp), Maxima y Emacs (elisp), Audacity (Nyquist), utilizan
versiones embebidas de Lisp, o también GIMP utiliza Scheme en su
sistema de plug-ins. Hablaré de un Lisp y de un Scheme, en
concreto, sobre embeddable common-lisp1, ecl
, y sobre
chibi-scheme
2.
Cuando hablo con algún programador sobre las virtudes de Emacs, pero también sobre Lisp, es habitual que aparezca la crítica de es un sistema viejuno, como algo negativo. Es cierto, lleva más de 40 años funcionando, evolucionando y puliendo errores ¿eso es malo? Desde mi punto de vista Lisp, en cualquiera de sus sabores, incluido Emacs ha conseguido una gran estabilidad.
Muchas de mis herramientas del día a día las tengo hechas en
elisp, como el código que sustenta este blog estático. Emacs me
sirve para casi todo: escribir informes con org-mode
, corregir
tests con herramientas propias, gestionar historias clínicas
cifradas, llevar la contabilidad junto con Ledger-cli3, leer
los blogs que me mantienen informado mediante RSS. Para algunas
pocas herramientas independientes he utilizado varios lenguajes
independientes, pero últimamente estoy moviendo la mayoría a
common-lisp, concretamente sbcl
.
Diferencias entre Common-Lisp y Scheme
Siendo dos dialectos de Lisp no se entienden entre ellos, de hecho
las podríamos considerar también como familias de sistemas Lisp.
Por un lado la familia common y por otro la familia scheme. En el
documento ANSI INCITS 226-1994 (R2004) está descrito el lenguaje
common-lisp
, aunque también existen varios dialectos Lisp que no
se ajustan a ese estándar, como el elisp
de Emacs, por ejemplo.
Tradicionalmente se dice que CL es un Lisp-2 mientras que Scheme
es un Lisp-1. Eso quiere decir que CL tiene dos listas de
definiciones, una para funciones y otra para variables. Por tanto en
Lisp se utilizan macros como defun
, para definir las funciones y
defvar
, o defparameter
, para definir variables. Además, en Lisp
las expresiones no son case-sensitive, toda expresión se traduce
internamente a mayúsculas. Así ocurre, que mientras en Scheme
podemos hacer:
~ > chibi-scheme > (define x 1) > (define X 12) > x 1 > X 12 >
En CL esto no ocurre:
~ > ecl ECL (Embeddable Common-Lisp) 21.2.1 (git:UNKNOWN) Copyright (C) 1984 Taiichi Yuasa and Masami Hagiya Copyright (C) 1993 Giuseppe Attardi Copyright (C) 2013 Juan J. Garcia-Ripoll Copyright (C) 2018 Daniel Kochmanski Copyright (C) 2021 Daniel Kochmanski and Marius Gerbershagen ECL is free software, and you are welcome to redistribute it under certain conditions; see file 'Copyright' for details. Type :h for Help. Top level in: #<process TOP-LEVEL 0x65bf80>. > (defvar x 1) X > (defvar X 12) X > x 1 > X 1 >
Por otro lado CL es un estándar prolijo e incluye, entre otras muchas cosas y detalles, la descripción de CLOS (Common Lisp Object System) que le permite a CL soportar la programación orientada a objetos.
Por el contrario, Scheme parte de una descripción minimalista cuyo objetivo no es acumular funcionalidades sino evitar las debilidades que las hacen necesarias. Esto hace que escribir un compilador o intérprete de Scheme sea más sencillo que uno de CL, pero dificulta la estandarización. Sin embargo, no está dejada de la mano la estandarización y para evitar el descontrol se establecieron las SRFI4, que vienen a poner un poco de estándar entre todos los scheme.
Como punto negativo extra, en Scheme es menos intuitivo el uso de las macros y me obliga a que me fije mejor en lo que estoy haciendo, en comparación con CL donde las macros me facilitan a primera vista qué es lo que se está definiendo.
Más allá de las características generales de las familias a los que
estas dos herramientas pertenecen, ambas permiten interaccionar con
código C. De hecho, permiten exportar nuestro programa a dicho
lenguaje y utilizar un compilador como gcc
para generar un
ejecutable. También ambos traen las herramientas habituales en
sistemas Lisp: REPL, intérprete para scripts, compilador de
byte-code.
embeddable common-lisp
En su web (https://ecl.common-lisp.dev/) se puede descargar el código fuente en un fichero tar-ball. Una vez descargado lo compilamos:
> ./configure --prefix=/path/local/opt > make > make install
El último comando, dependiendo de dónde quieras instalar la aplicación, debe contar con los permisos de ejecución de root si fuera necesario.
Para probar que todo funciona, he escrito el siguiente código:
(defun factorial (x) (if (= x 0) 1 (* x (factorial (- x 1))))) (print (factorial 2000))
La ejecución desde la línea de comandos:
> time ecl --load factorial.lisp --eval "(quit)" ;;; Loading "/home/notxor/blog/borradores/factorial.lisp" 331627509245063324117539338057632403828111720810578039457193543706038077905600822400273230859732592255402352941225834109258084817415293796131386633526343688905634058556163940605117252571870647856393544045405243957467037674108722970434684158343752431580877533645127487995436859247408032408946561507233250652797655757179671536718689359056112815871601717232657156110004214012420433842573712700175883547796899921283528996665853405579854903657366350133386550401172012152635488038268152152246920995206031564418565480675946497051552288205234899995726450814065536678969532101467622671332026831552205194494461618239275204026529722631502574752048296064750927394165856283531779574482876314596450373991327334177263608852490093506621610144459709412707821313732563831572302019949914958316470942774473870327985549674298608839376326824152478834387469595829257740574539837501585815468136294217949972399813599481016556563876034227312912250384709872909626622461971076605931550201895135583165357871492290916779049702247094611937607785165110684432255905648736266530377384650390788049524600712549402614566072254136302754913671583406097831074945282217490781347709693241556111339828051358600690594619965257310741177081519922564516778571458056602185654760952377463016679422488444485798349801548032620829890965857381751888619376692828279888453584639896594213952984465291092009103710046149449915828588050761867924946385180879874512891408019340074625920057098729578599643650655895612410231018690556060308783629110505601245908998383410799367902052076858669183477906558544700148692656924631933337612428097420067172846361939249698628468719993450393889367270487127172734561700354867477509102955523953547941107421913301356819541091941462766417542161587625262858089801222443890248677182054959415751991701271767571787495861619665931878855141835782092601482071777331735396034304969082070589958701381980813035590160762908388574561288217698136182483576739218303118414719133986892842344000779246691209766731651433494437473235636572048844478331854941693030124531676232745367879322847473824485092283139952509732505979127031047683601481191102229253372697693823670057565612400290576043852852902937606479533458179666123839605262549107186663869354766108455046198102084050635827676526589492393249519685954171672419329530683673495544004586359838161043059449826627530605423580755894108278880427825951089880635410567917950974017780688782869810219010900148352061688883720250310665922068601483649830532782088263536558043605686781284169217133047141176312175895777122637584753123517230990549829210134687304205898014418063875382664169897704237759406280877253702265426530580862379301422675821187143502918637636340300173251818262076039747369595202642632364145446851113427202150458383851010136941313034856221916631623892632765815355011276307825059969158824533457435437863683173730673296589355199694458236873508830278657700879749889992343555566240682834763784685183844973648873952475103224222110561201295829657191368108693825475764118886879346725191246192151144738836269591643672490071653428228152661247800463922544945170363723627940757784542091048305461656190622174286981602973324046520201992813854882681951007282869701070737500927666487502174775372742351508748246720274170031581122805896178122160747437947510950620938556674581252518376682157712807861499255876132352950422346387878954850885764466136290394127665978044202092281337987115900896264878942413210454925003566670632909441579372986743421470507213588932019580723064781498429522595589012754823971773325722910325760929790733299545056388362640474650245080809469116072632087494143973000704111418595530278827357654819182002449697761111346318195282761590964189790958117338627206088910432945244978535147014112442143055486089639578378347325323595763291438925288393986256273242862775563140463830389168421633113445636309571965978466338551492316196335675355138403425804162919837822266909521770153175338730284610841886554138329171951332117895728541662084823682817932512931237521541926970269703299477643823386483008871530373405666383868294088487730721762268849023084934661194260180272613802108005078215741006054848201347859578102770707780655512772540501674332396066253216415004808772403047611929032210154385353138685538486425570790795341176519571188683739880683895792743749683498142923292196309777090143936843655333359307820181312993455024206044563340578606962471961505603394899523321800434359967256623927196435402872055475012079854331970674797313126813523653744085662263206768837585132782896252333284341812977624697079543436003492343159239674763638912115285406657783646213911247447051255226342701239527018127045491648045932248108858674600952306793175967755581011679940005249806303763141344412269037034987355799916009259248075052485541568266281760815446308305406677412630124441864204108373119093130001154470560277773724378067188899770851056727276781247198832857695844217588895160467868204810010047816462358220838532488134270834079868486632162720208823308727819085378845469131556021728873121907393965209260229101477527080930865364979858554010577450279289814603688431821508637246216967872282169347370599286277112447690920902988320166830170273420259765671709863311216349502171264426827119650264054228231759630874475301847194095524263411498469508073390080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ________________________________________________________ Executed in 65.03 millis fish external usr time 80.18 millis 454.00 micros 79.73 millis sys time 15.14 millis 194.00 micros 14.95 millis
En otra ocasión ya hice algunas pruebas de ejecución de diversos
intérpretes de Lisp, por eso añado los tiempos de ejecución. Y con
ánimo de comparar, también he hecho una versión tail-recursive. Si
alguien tiene dudas de qué es eso, lo expliqué mejor en el curso de
elisp
para no programadores en el artículo de funciones recursivas,
especialmente porque en ese artículo se utiliza la función auxiliar
externa, mientras que en el siguiente código la función auxiliar es
interna y puede despistar un poco a los no habituales de Lisp al
utilizar la forma labels
para definir una función.
(defun factorial (x) (labels ((itera (n total) (if (= n 0) total (itera (- n 1) (* total n))))) (itera x 1))) (print (factorial 2000))
Llamada desde línea de comandos con ecl
:
> time ecl --load factorial.lisp --eval "(quit)" ;;; Loading "/home/notxor/blog/borradores/factorial.lisp" 331627509245063324117539338057632403828111720810578039457193543706038077905600822400273230859732592255402352941225834109258084817415293796131386633526343688905634058556163940605117252571870647856393544045405243957467037674108722970434684158343752431580877533645127487995436859247408032408946561507233250652797655757179671536718689359056112815871601717232657156110004214012420433842573712700175883547796899921283528996665853405579854903657366350133386550401172012152635488038268152152246920995206031564418565480675946497051552288205234899995726450814065536678969532101467622671332026831552205194494461618239275204026529722631502574752048296064750927394165856283531779574482876314596450373991327334177263608852490093506621610144459709412707821313732563831572302019949914958316470942774473870327985549674298608839376326824152478834387469595829257740574539837501585815468136294217949972399813599481016556563876034227312912250384709872909626622461971076605931550201895135583165357871492290916779049702247094611937607785165110684432255905648736266530377384650390788049524600712549402614566072254136302754913671583406097831074945282217490781347709693241556111339828051358600690594619965257310741177081519922564516778571458056602185654760952377463016679422488444485798349801548032620829890965857381751888619376692828279888453584639896594213952984465291092009103710046149449915828588050761867924946385180879874512891408019340074625920057098729578599643650655895612410231018690556060308783629110505601245908998383410799367902052076858669183477906558544700148692656924631933337612428097420067172846361939249698628468719993450393889367270487127172734561700354867477509102955523953547941107421913301356819541091941462766417542161587625262858089801222443890248677182054959415751991701271767571787495861619665931878855141835782092601482071777331735396034304969082070589958701381980813035590160762908388574561288217698136182483576739218303118414719133986892842344000779246691209766731651433494437473235636572048844478331854941693030124531676232745367879322847473824485092283139952509732505979127031047683601481191102229253372697693823670057565612400290576043852852902937606479533458179666123839605262549107186663869354766108455046198102084050635827676526589492393249519685954171672419329530683673495544004586359838161043059449826627530605423580755894108278880427825951089880635410567917950974017780688782869810219010900148352061688883720250310665922068601483649830532782088263536558043605686781284169217133047141176312175895777122637584753123517230990549829210134687304205898014418063875382664169897704237759406280877253702265426530580862379301422675821187143502918637636340300173251818262076039747369595202642632364145446851113427202150458383851010136941313034856221916631623892632765815355011276307825059969158824533457435437863683173730673296589355199694458236873508830278657700879749889992343555566240682834763784685183844973648873952475103224222110561201295829657191368108693825475764118886879346725191246192151144738836269591643672490071653428228152661247800463922544945170363723627940757784542091048305461656190622174286981602973324046520201992813854882681951007282869701070737500927666487502174775372742351508748246720274170031581122805896178122160747437947510950620938556674581252518376682157712807861499255876132352950422346387878954850885764466136290394127665978044202092281337987115900896264878942413210454925003566670632909441579372986743421470507213588932019580723064781498429522595589012754823971773325722910325760929790733299545056388362640474650245080809469116072632087494143973000704111418595530278827357654819182002449697761111346318195282761590964189790958117338627206088910432945244978535147014112442143055486089639578378347325323595763291438925288393986256273242862775563140463830389168421633113445636309571965978466338551492316196335675355138403425804162919837822266909521770153175338730284610841886554138329171951332117895728541662084823682817932512931237521541926970269703299477643823386483008871530373405666383868294088487730721762268849023084934661194260180272613802108005078215741006054848201347859578102770707780655512772540501674332396066253216415004808772403047611929032210154385353138685538486425570790795341176519571188683739880683895792743749683498142923292196309777090143936843655333359307820181312993455024206044563340578606962471961505603394899523321800434359967256623927196435402872055475012079854331970674797313126813523653744085662263206768837585132782896252333284341812977624697079543436003492343159239674763638912115285406657783646213911247447051255226342701239527018127045491648045932248108858674600952306793175967755581011679940005249806303763141344412269037034987355799916009259248075052485541568266281760815446308305406677412630124441864204108373119093130001154470560277773724378067188899770851056727276781247198832857695844217588895160467868204810010047816462358220838532488134270834079868486632162720208823308727819085378845469131556021728873121907393965209260229101477527080930865364979858554010577450279289814603688431821508637246216967872282169347370599286277112447690920902988320166830170273420259765671709863311216349502171264426827119650264054228231759630874475301847194095524263411498469508073390080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ________________________________________________________ Executed in 70.60 millis fish external usr time 67.38 millis 482.00 micros 66.90 millis sys time 18.84 millis 255.00 micros 18.58 millis
Por comparar la eficiencia con otro CL, que utilizo habitualmente,
lo he ejecutado con sbcl
. Llamada desde línea de comandos con
sbcl
:
> time sbcl --script factorial.lisp
331627509245063324117539338057632403828111720810578039457193543706038077905600822400273230859732592255402352941225834109258084817415293796131386633526343688905634058556163940605117252571870647856393544045405243957467037674108722970434684158343752431580877533645127487995436859247408032408946561507233250652797655757179671536718689359056112815871601717232657156110004214012420433842573712700175883547796899921283528996665853405579854903657366350133386550401172012152635488038268152152246920995206031564418565480675946497051552288205234899995726450814065536678969532101467622671332026831552205194494461618239275204026529722631502574752048296064750927394165856283531779574482876314596450373991327334177263608852490093506621610144459709412707821313732563831572302019949914958316470942774473870327985549674298608839376326824152478834387469595829257740574539837501585815468136294217949972399813599481016556563876034227312912250384709872909626622461971076605931550201895135583165357871492290916779049702247094611937607785165110684432255905648736266530377384650390788049524600712549402614566072254136302754913671583406097831074945282217490781347709693241556111339828051358600690594619965257310741177081519922564516778571458056602185654760952377463016679422488444485798349801548032620829890965857381751888619376692828279888453584639896594213952984465291092009103710046149449915828588050761867924946385180879874512891408019340074625920057098729578599643650655895612410231018690556060308783629110505601245908998383410799367902052076858669183477906558544700148692656924631933337612428097420067172846361939249698628468719993450393889367270487127172734561700354867477509102955523953547941107421913301356819541091941462766417542161587625262858089801222443890248677182054959415751991701271767571787495861619665931878855141835782092601482071777331735396034304969082070589958701381980813035590160762908388574561288217698136182483576739218303118414719133986892842344000779246691209766731651433494437473235636572048844478331854941693030124531676232745367879322847473824485092283139952509732505979127031047683601481191102229253372697693823670057565612400290576043852852902937606479533458179666123839605262549107186663869354766108455046198102084050635827676526589492393249519685954171672419329530683673495544004586359838161043059449826627530605423580755894108278880427825951089880635410567917950974017780688782869810219010900148352061688883720250310665922068601483649830532782088263536558043605686781284169217133047141176312175895777122637584753123517230990549829210134687304205898014418063875382664169897704237759406280877253702265426530580862379301422675821187143502918637636340300173251818262076039747369595202642632364145446851113427202150458383851010136941313034856221916631623892632765815355011276307825059969158824533457435437863683173730673296589355199694458236873508830278657700879749889992343555566240682834763784685183844973648873952475103224222110561201295829657191368108693825475764118886879346725191246192151144738836269591643672490071653428228152661247800463922544945170363723627940757784542091048305461656190622174286981602973324046520201992813854882681951007282869701070737500927666487502174775372742351508748246720274170031581122805896178122160747437947510950620938556674581252518376682157712807861499255876132352950422346387878954850885764466136290394127665978044202092281337987115900896264878942413210454925003566670632909441579372986743421470507213588932019580723064781498429522595589012754823971773325722910325760929790733299545056388362640474650245080809469116072632087494143973000704111418595530278827357654819182002449697761111346318195282761590964189790958117338627206088910432945244978535147014112442143055486089639578378347325323595763291438925288393986256273242862775563140463830389168421633113445636309571965978466338551492316196335675355138403425804162919837822266909521770153175338730284610841886554138329171951332117895728541662084823682817932512931237521541926970269703299477643823386483008871530373405666383868294088487730721762268849023084934661194260180272613802108005078215741006054848201347859578102770707780655512772540501674332396066253216415004808772403047611929032210154385353138685538486425570790795341176519571188683739880683895792743749683498142923292196309777090143936843655333359307820181312993455024206044563340578606962471961505603394899523321800434359967256623927196435402872055475012079854331970674797313126813523653744085662263206768837585132782896252333284341812977624697079543436003492343159239674763638912115285406657783646213911247447051255226342701239527018127045491648045932248108858674600952306793175967755581011679940005249806303763141344412269037034987355799916009259248075052485541568266281760815446308305406677412630124441864204108373119093130001154470560277773724378067188899770851056727276781247198832857695844217588895160467868204810010047816462358220838532488134270834079868486632162720208823308727819085378845469131556021728873121907393965209260229101477527080930865364979858554010577450279289814603688431821508637246216967872282169347370599286277112447690920902988320166830170273420259765671709863311216349502171264426827119650264054228231759630874475301847194095524263411498469508073390080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
________________________________________________________
Executed in 27.22 millis fish external
usr time 0.00 millis 0.00 micros 0.00 millis
sys time 16.03 millis 728.00 micros 15.30 millis
La diferencia entre las dos ejecuciones es significativa, en torno a
una tercera parte de tiempo que ecl
. La diferencia se la achaco no
solo a que sbcl
sea, según se dice, el CL más rápido, también a
que durante la primera ejecución compila el script a byte-code. Las
siguientes llamadas reducen su tiempo de ejecución al ejecutar el
binario. Luego volveré un poco sobre esta explicación.
chibi-scheme
Éste lo bajé de su repositorio y lo compilé. Viene con un archivo
configure
y yo piqué. Las instrucciones de compilación están en el
README.md
y son muy sencillas:
> make --prefix=path/local/opt > make --prefix=path/local/opt install
No me pidió ninguna dependencia ni dio ningún error, por lo que supongo que mi sistema ya las cumplía todas. Para probarlo escribí el código equivalente al anterior para Scheme.
(define (factorial x) (if (= x 0) 1 (* x (factorial (- x 1))))) (display (factorial 2000))
También cabe utilizar chibi-scheme
como lenguaje de script, para
eso hay que añadir un shebang al fichero .scm
y, puesto que está
diseñado para ser minimalista, hay que importar las librerías
básicas. Sería algo así como:
#!/home/notxor/opt/bin/chibi-scheme
(import (scheme base) (chibi))
Dándole permiso de ejecución al script lo podemos llamar
directamente. La instrucción import
no es necesaria si lo llamamos
desde la línea de comandos. Me pareció que al ejecutar desde el
inicio con esos paquetes cargados, la siguiente forma de ejecutar el
código era ligeramente más rápida que la versión script:
time chibi-scheme -q factorial.scm -p "(factorial 2000)"
La opción -q
carga el módulo de código y la opción -p
evalúa y
muestra el resultado de una expresión. El código del módulo lo muestro
a continuación dejando como comentarios el shebang y la importación
de módulos sólo a modo de muestra. Como dije antes, utilizándolo de
esa otra manera, la carga de los módulos, me pareció que penaliza el
tiempo de ejecución total del script.
;; #!/usr/local/bin/chibi-scheme ;; (import (scheme base) (chibi)) (define (factorial x) (if (= x 0) 1 (* x (factorial (- x 1))))) (display (factorial 200))
De la misma manera que hice una versión tail-recursive para CL, la hice para Scheme:
(define (factorial x) (define (itera n total) (if (= n 0) total (itera (- n 1) (* total n)))) (itera x 1)) (display (factorial 2000))
Veamos los resultados de las pruebas.
Comparación de tiempos de ejecución
Utilizando ambas herramientas como shell scripts los tiempos medios de ejecución obtenidos son:
Lenguaje | tiempo | tail-recursive |
---|---|---|
chibi-scheme |
74,46 ms | 79,90 ms |
" script | 204,87 ms | 210,34 ms |
ecl |
77,33 ms | 72,70 ms |
guile 5 |
17,48 ms | 18,45 ms |
sbcl 5 |
28,82 ms | 27,80 ms |
¿Por qué son tan rápidos guile
y sbcl
? En realidad, tanto el
scheme como el clisp son tan rápidos porque durante la primera
ejecución generan byte-code que acelera las posteriores ejecuciones.
Si eliminas el fichero compilado, en cada ejecución, los tiempos no
muestran una mejora tan radical en comparación a sus primos
embebibles.
Por otro lado vemos que la versión recursiva pura, en general, es ligeramente más rápida que la versión tail-recursive. Por contrapartida, la versión recursiva necesita más memoria porque tiene que desenrollar la madeja de la recursión para volver a enrollarla después. La versión tail-recursive gasta más tiempo en llamadas entre funciones pero el gasto de memoria es mínimo. Sabiendo esto, podemos elegir una función u otra dependiendo de las necesidades de nuestro sistema. En resumen, hay que tener cuidado con las iteraciones puras, con especial atención a los datos que se iteran, porque es posible que ocupen más memoria de la que nos podemos permitir, sobre todo si escasea y nuestra iteración se hace sobre listas enormes.
Conclusiones
Tanto chibi-scheme
como ecl
me han parecido unas magníficas
herramientas, especialmente la segunda, pues no hay muchos CL que
puedan utilizarse de manera embebida en aplicaciones, mientras
Scheme hay varios que pueden utilizarse de ese modo.
Notas al pie de página:
Scheme Requests for Implementation. En el caso de
chibi-scheme
, reconoce estos estándares: https://synthcode.com/scheme/chibi/#h2_StandardModules
Tiempo de ejecución por la generación de byte-code intermedio la primera ejecución.
Comentarios