¿Por qué no es posible crear un práctico convertidor de código fuente de Perl a Python?

Sería bueno si existiera un progtwig que transforme automáticamente el código Perl en código Python, haciendo que el progtwig Python resultante sea tan legible y fácil de mantener como el original, y mucho menos funcione de la misma manera.

La solución más obvia simplemente invocaría perl través de utilidades de Python:

 #!/usr/bin/python os.exec("tail -n -2 "+__file__+" | perl -") ...the rest of file is the original perl program... 

Sin embargo, el código resultante no es un código de Python, es esencialmente un código de Perl. El convertidor potencial debería convertir las construcciones y los modismos de Perl a un código Python fácil de leer, debería conservar los nombres de las variables y las subrutinas (es decir, el resultado no debería verse confuso) y no debería destruir demasiado el flujo de trabajo.

Tal conversión es obviamente muy difícil. La dureza de la conversión depende de la cantidad de características de Perl y de las construcciones sintácticas, que no tienen equivalentes de Python no ofuscados y fáciles de leer. Creo que la gran cantidad de tales características hace que tal conversión automática sea prácticamente imposible (mientras exista la posibilidad teórica ).

Entonces, ¿podría nombrar los lenguajes de Perl y las características de syntax que no se pueden express en Python de forma tan concisa como en el código original de Perl?

Edición : algunas personas vincularon a los conventos de Python a Perl y dedujeron, sobre esta base, que también debería ser fácil escribir Perl-to-Python. Sin embargo, estoy seguro de que la conversión a Python tiene una mayor demanda; Todavía este convertidor aún no está escrito, ¡mientras que lo contrario ya ha sido! Lo que solo hace que mi confianza en la imposibilidad de escribir un buen conversor a Python sea más sólida.

Solo para ampliar algunas de las otras listas aquí, estas son algunas construcciones de Perl que probablemente son muy torpes en Python (si es posible).

  • scope dynamic (a través de la palabra clave local )
  • Manipulación de typeglob (múltiples variables con el mismo nombre)
  • Formatos (tienen una syntax propia)
  • cierres sobre variables mutables
  • pragmas
  • subrutinas de mysub() = 5; ( mysub() = 5; código de tipo)
  • filtros de fuente
  • contexto (lista vs escalar, y la forma en que el código llamado puede inspeccionar esto con wantarray )
  • tipo de coerción / escritura dinámica
  • Cualquier progtwig que use cadena eval

La lista continúa y alguien podría intentar crear un mapeo entre todas las construcciones análogas, pero al final será un fracaso por una simple razón.

Perl no puede ser analizado estáticamente. Las definiciones en el código Perl (particularmente las de los bloques BEGIN) cambian la forma en que el comstackdor interpretará el código restante. Entonces, para los progtwigs no triviales, la conversión de Perl => Python sufre el problema de la detención.

No hay forma de saber exactamente cómo se comstackrá todo el progtwig hasta que el progtwig haya terminado de ejecutarse, y es teóricamente posible crear un progtwig Perl que compile de manera diferente cada vez que se ejecute. Lo que significa que un progtwig de Perl podría asignarse a un número infinito de progtwigs de Python, cuyo correcto solo se conoce después de ejecutar el progtwig original en el intérprete de perl.

Tu mejor convertidor de Perl a Python es probablemente de 23 años, recién graduado de la universidad y está buscando trabajo.

Por qué Perl no es Python.

  1. Perl tiene declaraciones de las que Python carece más o menos. Si bien es probable que pueda crear declaraciones coincidentes, la syntax será tan diferente a Perl que dificultará que se llame una “traducción”. Realmente tendrías que cocinar algunas cosas elegantes de Python para hacerlo tan conciso como el Perl original.

  2. Perl tiene una semántica de tiempo de ejecución que es tan diferente a Python que hace que la traducción sea muy desafiante. Veremos un ejemplo a continuación.

  3. Perl tiene estructuras de datos que son lo suficientemente diferentes de Python que la traducción es difícil.

  4. Los hilos de Perl no comparten datos por defecto. Solo se pueden compartir elementos de datos seleccionados. Los hilos de Python tienen datos más comunes de “todo compartido”.

Un ejemplo de # 2 debería ser suficiente.

Perl:

 do_something || die() 

Donde do_algo es cualquier statement de cualquier tipo.

Para traducir automáticamente esto a Python, tendrías que envolver cada || die() statement || die() en

 try: python_version_of_do_something except OrdinaryStatementFailure, e: die() sys.exit() 

Donde la formulación más común

Perl

 do_something 

Se convertiría en este uso simple – sin pensar – traducción de la fuente

 try: python_version_of_do_something except OrdinaryStatementFailure, e: pass 

Y por supuesto,

Perl

 do_this || do_that || die() 

Es incluso más complejo de traducir en Python.

Y

Perl

 do_this && do_that || die() 

realmente empuje el sobre. Mi Perl está oxidado, así que no puedo recordar la semántica precisa de este tipo de cosas. Pero tienes que entender totalmente la semántica para elaborar una implementación Pythonic.

Los ejemplos de Python no son buenos Python. Escribir un buen Python requiere “pensamiento”, algo que una traducción automática no puede hacer.

Y cada construcción de Perl tendría que ser “envuelta” de esa manera para obtener la semántica de Perl original en una forma pythonica.

Ahora, haga un análisis similar para cada característica de Perl.

No es imposible, solo llevaría mucho trabajo.

Por cierto, hay Perthon , un traductor de Python a Perl. Simplemente parece que nadie está dispuesto a hacer uno que vaya al otro lado.

EDITAR: Creo que podría haber encontrado la razón por la que un traductor de Python a Perl es mucho más fácil de implementar. Es porque Python te permite jugar con el AST de un script. Ver módulo analizador.

Perl puede construirse experimentalmente para recostackr información adicional (por ejemplo, comentarios) durante la comstackción del código perl e incluso emitir los resultados como XML. No parece haber ninguna documentación de esto fuera de la fuente, excepto por: http://search.cpan.org/perldoc/perl5100delta#MAD

Esto debería ser útil en la construcción de un traductor. Espero que obtengas el 80% del camino con bastante facilidad, el 95% con gran dificultad y nunca mucho mejor que eso. Hay demasiadas cosas que no se mapean bien.

Fundamentalmente, estos son dos idiomas diferentes. La conversión de uno a otro y el resultado puede ser legible en su mayor parte significaría que el software tendría que ser capaz de reconocer y generar expresiones idiomáticas de código, y ser capaz de realizar un análisis estático.

El significado de un progtwig puede estar definido exactamente por la definición del lenguaje, pero el progtwigdor no necesariamente requirió todos los detalles. La prueba del progtwigdor de CA si el valor que devolvió un printf() es negativo está verificando una condición de error, y normalmente no le importa el valor exacto. if (printf("%s","...") < 0) exit(); se puede traducir a Perl como print "..." or die(); . Es posible que estas declaraciones no signifiquen exactamente lo mismo, pero normalmente serán lo que el progtwigdor quiere decir, y para crear el código C o Perl idiomático del código Perl o C idiomático, el traductor debe tener esto en cuenta.

Dado que los diferentes lenguajes informáticos tienden a tener diferentes semánticas diferentes para cosas similares, normalmente es imposible traducir un idioma a otro y tener el mismo significado exacto en forma legible. Para crear un código legible, el traductor debe comprender qué pretendía hacer el progtwigdor, y eso es realmente difícil.

Además, sería más fácil traducir de Python a Perl en lugar de Perl a Python. Python está pensado como un lenguaje sencillo con formas claras y estándar de hacer las cosas, mientras que Perl es un lenguaje excesivamente complejo con el lema "Hay más de una forma de hacerlo". Traducir una expresión de Python a una de las innumerables expresiones correspondientes de Perl es más fácil que averiguar qué significó el progtwigdor de Perl y expresslo en Python.

  • El scope y el espacio de nombres de Python son diferentes de Perl.

  • En Python, todo es un objeto. En Perl, todo bajo el capó parece ser una lista / hash / escalar / referencia / función. Esto induce diferentes enfoques de diseño y expresiones idiomáticas.

  • Perl tiene bloques de códigos anónimos y puede generar cierres sobre la marcha con algunas sucursales. Estoy bastante seguro de que no es una característica de python.

Creo que un tipo muy inteligente podría analizar estáticamente la mayor parte de Perl y producir un progtwig que tome pequeños progtwigs de Perl y genere progtwigs de Python que hagan el mismo trabajo.

Tengo muchas más dudas sobre la viabilidad de una traducción Perl grande y / o retorcida. Algunos de nosotros escribimos un código realmente funky a veces … 🙂

Esto es imposible simplemente porque ni siquiera se puede analizar correctamente el código de Perl. Ver Perl no puede analizarse: una prueba formal para más detalles.

El conjunto de módulos B de Malcolm Beattie sería el único punto de partida sensato para algo como esto, aunque tengo otras respuestas en que este sería un problema difícil de resolver. En general, traducir el sentido de un lenguaje de alto nivel a otro lenguaje de alto nivel requiere un traductor de alto nivel y, por el momento, eso puede significar solo un ser humano.

La dificultad de este problema, para cualquier par de idiomas, se debe a diferencias fundamentales en la naturaleza de los idiomas en cuestión, como la semántica de tiempo de ejecución y los lenguajes comunes, por no mencionar las bibliotecas.

La razón por la cual es casi imposible crear un traductor genérico de un lenguaje de alto nivel a otro, es que el progtwig solo describe CÓMO y no POR QUÉ (esta es la razón de los comentarios en el código fuente).

Para crear un progtwig significativo en otro lenguaje de alto nivel, usted (o el progtwig traductor) necesita saber POR QUÉ para poder crear el mejor progtwig posible. Si no puede hacer eso, todo lo que puede hacer es esencialmente crear un intérprete de Python para la versión comstackda del progtwig Perl.

En otras palabras, para hacer esto correctamente, necesitas ir fuera de la caja, y esto es muy difícil para una computadora.

NullUserException básicamente lo resumió: ciertamente se puede hacer; Solo sería un enorme esfuerzo hacer eso. Algunas utilidades de conversión de lenguaje que he visto comstackr a un lenguaje intermedio (como el CIL de .NET) y luego descomstackrlo en el idioma deseado. No he visto ninguna para Perl a Python. Sin embargo, puede encontrar un convertidor de Python a Perl aquí , aunque es probable que sea poco útil para usted a menos que esté intentando crear el suyo propio, en cuyo caso puede proporcionar alguna referencia útil.

Edición: si solo necesita la funcionalidad exacta en un script de Python, PyPerl puede serle de alguna utilidad.