Notxor tiene un blog

Defenestrando la vida

Lisp y scheme embebidos

Notxor
2023-08-12

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-scheme2.

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
guile5 17,48 ms 18,45 ms
sbcl5 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:

4

Scheme Requests for Implementation. En el caso de chibi-scheme, reconoce estos estándares: https://synthcode.com/scheme/chibi/#h2_StandardModules

5

Tiempo de ejecución por la generación de byte-code intermedio la primera ejecución.

Categoría: lisp scheme

Comentarios

Debido a algunos ataques mailintencionados a través de la herramienta de comentarios, he decidido no proporcionar dicha opción en el Blog. Si alguien quiere comentar algo, me puede encontrar en esta cuenta de Mastodon, también en esta otra cuenta de Mastodon y en Diaspora con el nick de Notxor.

Si usas habitualmente XMPP (si no, te recomiendo que lo hagas), puedes encontrar también un pequeño grupo en el siguiente enlace: notxor-tiene-un-blog@salas.suchat.org

Disculpen las molestias.