2 puntos por GN⁺ 2023-11-27 | 1 comentarios | Compartir por WhatsApp
  • El port de fish-shell a Rust está “mayormente” completado y, según cómo se mida, el avance se estima entre 60% por eliminación de C++ SLOC y 74% por Rust SLOC frente a C++ SLOC
  • La tarea más grande que queda es portar reader y el sistema de entrada; reader con 3.5k líneas, manejo de pantalla con 1.3k, input con 1k y pager con 700 líneas están fuertemente acoplados entre sí
  • Todo el código en C++ será eliminado y no se planea publicar una release parcial en Rust; el objetivo es que una release como fish 4.0 incluya solo Rust y 0 de C++
  • Nunca se planeó un port para Windows; la transición a Rust no resuelve el problema del soporte para Windows, y usuarios de MSYS2/cygwin temen que la ausencia de esos targets en Rust pueda bloquear futuras actualizaciones
  • El rendimiento del port terminado aún no está definido; los resultados iniciales son prometedores, pero en algunos casos podría ser cerca de 20% más lento, por lo que consideran necesario un beta para la primera release en Rust

Estado del port a Rust

  • La reescritura de fish-shell en Rust está “mayormente” completada
  • El porcentaje de avance cambia según el criterio usado
    • Por eliminación de C++ SLOC: 60%
    • Por Rust SLOC frente a C++ SLOC: 74%
  • Parte del código es andamiaje duplicado que puede eliminarse cuando desaparezca su último llamador
    • Por ejemplo, wgetopt ya fue traducido a Rust, pero la versión en C++ se mantiene hasta que se porte el último llamador en C++
    • Esto es más simple que añadir código de conversión a todos los llamadores en C++
  • Después de que desaparezca el último llamador, hay partes que se limpian en efecto dominó al eliminar el código duplicado

Grandes tareas pendientes

  • El componente pendiente más grande es reader y el sistema de entrada
  • El código relacionado está fuertemente acoplado
    • reader: 3.5k líneas
    • manejo de pantalla: 1.3k líneas
    • input: 1k líneas
    • pager: 700 líneas
  • Después queda algo de código remanente y la eliminación de C++ del sistema de build
    • eliminar cmake
    • hacer que cargo se encargue de todo lo necesario
    • cargo también debe encargarse de compilar e instalar la documentación y los archivos de completion
  • El build de fish no solo compila código Rust, también incluye varios artefactos auxiliares, así que no es una transición simple
  • Este trabajo no es del tipo adecuado para una “drive-by contribution”

Plan de releases y flujo de versiones

  • fish-shell no planea publicar una release parcial en Rust
  • Por ejemplo, fish 4.0 estaría compuesto completamente por Rust y tendría 0 de C++
  • En general dejaron de hacer betas y release candidates, pero consideran que esta transición sí justifica un beta
    • Antes dejaron de hacer betas y release candidates porque no recibían suficientes pruebas
  • También quieren una release intermedia 3.7.0 basada en C++ antes de pasar a la versión en Rust
    • Para que sirva como mejor punto de partida para plataformas que no puedan manejar la versión en Rust
    • 3.7.0 sería una versión de 3.6.1 con algunos cambios backporteados
  • El trabajo de 3.7.0 avanza en la rama Integration_3.7.0 branch
    • También hay un CHANGELOG preliminar
    • Entre los cambios principales están timeouts de combinaciones de teclas, mejoras al history-pager, correcciones de glitches de renderizado y glob más rápido

Archivos pendientes y alcance concreto

  • Al 1 de diciembre de 2023, la lista de archivos pendientes es la siguiente
src/fish_indent_common.cpp
src/fish_indent.cpp
src/fish_key_reader.cpp
src/builtins/bind.cpp
src/builtins/commandline.cpp
src/fish_tests.cpp
src/pager.cpp
src/reader.cpp
  • Esta lista muestra el alcance pendiente del port de C++ por archivo

Aclaraciones y restricciones

  • Todo el código en C++ será eliminado
  • No hay planes para un port a Windows, y nunca los hubo
    • C++ también tiene buen soporte en Windows, así que Rust por sí mismo no resuelve el problema del port a Windows
    • El problema del port a Windows no es el lenguaje, sino que Windows no es Unix
  • No cambiarán el nombre ni la mascota
  • Es poco probable que agreguen “written in Rust” al tagline
    • En fishshell.com sí podrían mencionar que está escrito en Rust
    • En discusiones adicionales de septiembre de 2024 se reafirmó la postura de no poner “written in rust” en el tagline
  • Aún no se sabe cómo rendirá el port terminado
    • Los resultados iniciales son prometedores
    • En algunos casos podría ser cerca de 20% más lento
    • Incluso después de terminar el port inicial, el proyecto no estará terminado y seguirá habiendo mucho por hacer

Preocupaciones de usuarios de Windows y MSYS2/cygwin

  • Un usuario explicó que usa fish en un entorno MSYS2 y que, como MSYS2 proporciona utilidades POSIX, fish funciona bien allí
  • Como Rust no ofrece targets para cygwin ni MSYS2, le preocupa que después de la reescritura en Rust ya no se pueda compilar fish para esos targets de cygwin o MSYS2
  • Este usuario cree que la transición a Rust podría bloquear las actualizaciones para algunos usuarios de fish en Windows
  • La preocupación no se plantea como una crítica al trabajo ni al lenguaje, sino como un recordatorio de la limitación de que Windows no es Unix

1 comentarios

 
GN⁺ 2023-11-27
Opiniones de Hacker News
  • Si entendí bien, me sorprende que estén haciendo una reescritura gradual de C++ a Rust y aun así mantengan el proyecto funcionando hasta el final.
    El ritmo de avance también es muy rápido, y si todavía no probaste fish, lo recomiendo mucho. Es un shell cómodo de usar incluso sin personalizarlo, porque sus valores predeterminados son buenos; desde que me pasé desde bash hace unos años, no he pensado en volver.
    De paso, ya no tengo que googlear cada vez la sintaxis de los bucles for de bash, que se usa poco y tampoco es intuitiva.

    • No parece que lo estén haciendo de forma gradual.
      Dicen que “no planean hacer un release con Rust mezclado parcialmente”, y que, por ejemplo, fish 4.0 saldría como 100% Rust, 0% C++. Parece que también planean sacar antes una 3.7.0 solo en C++, para que sea un mejor punto de partida para las plataformas que no puedan manejar la versión en Rust.
      https://github.com/fish-shell/fish-shell/discussions/10123#d...
    • Para scripts sigo usando Bash, o directamente saco Python/Perl, pero para usar la terminal Fish definitivamente es mejor.
    • Como ejemplo de bucle en Bash fácil de recordar, para un índice incremental se puede escribir for ((i = 0; i < 10; i++)); do echo $i; done.
      Para recorrer un arreglo, se puede hacer algo como definir foo[0]=a, foo[1]=b y luego usar for i in ${foo[@]}; do echo $i; done.
  • La motivación de la reescritura está explicada con más detalle.
    https://github.com/fish-shell/fish-shell/pull/9512#issuecomm...

    • El texto del maintainer es maduro y lógico, con una dosis justa de humor y firmeza, al punto de que me hizo pasar de “tal vez debería probar Fish algún día” a pensar que quizá me estaba perdiendo un gran proyecto.
    • Que vean portar a C++17 como “demasiado engorroso”, pero consideren aceptable reescribir todo en un lenguaje nuevo, dice bastante.
      Al final, creo que es difícil ganarle a la narrativa general del mundo del desarrollo de perseguir lo nuevo y brillante. Aun así, aunque no uso Fish, espero que les vaya bien.
  • Como alguien que usa Fish todos los días en unos cuatro sistemas operativos y le gusta, esta reescritura me entusiasma mucho, y el ritmo de avance sorprende si se considera el tamaño y la complejidad del codebase.
    Creo que también hará que a mucha gente, incluyéndome, le resulte más fácil contribuir. Algo menos comentado, pero que me entusiasma aún más, es el plan de que fish pase a usar UTF-8 en lugar de wchar_t en el futuro. UCS2 y UTF-16 han sido un dolor de cabeza para el software, y Rust hace mucho más cómodo trabajar con UTF-8.

    • Dar soporte a varios compiladores en una misma base de código lo vuelve más complejo.
      sizeof(wchar_t) es de 2 bytes en MSVC, por lo que es UTF-16, y de 4 bytes en gcc, por lo que es UTF-32.
  • Fish es un shell subestimado.
    Toma decisiones fuertes, como renunciar a la compatibilidad POSIX, y el resultado es un shell muy bueno. Lo uso desde hace más de 10 años y todavía me gusta.
    El scripting del shell Fish también es muy cómodo de usar, algo así como un bash ergonómico. Todo proyecto tiene defectos, pero nunca me ha bloqueado realmente lo que quería hacer.

  • Como usuario de zsh + spaceship, me da curiosidad qué ventajas tendría pasar Fish a ser mi shell principal.
    No uso muchos scripts de bash, así que la parte de scripting me importa menos.

    • Si ya configuraste zsh a tu gusto, probablemente no haya muchas ventajas grandes.
      La gran ventaja de Fish es que está cerca de ser un shell ideal sin configuración. El autocompletado funciona de entrada, es fácil explorar el historial, también completa comandos en función del historial, y elegir el prompt es tan simple como abrir el navegador. Se puede personalizar en profundidad como zsh, pero incluso con los valores predeterminados ya es un shell bastante bueno.
    • La razón por la que elegí Fish en vez de zsh en 2017 fue que las funciones que quería venían incluidas por defecto y, en mi percepción, era mucho más rápido.
      Desde entonces me gustó haber dejado de dedicar casi nada de tiempo al mantenimiento de la configuración del shell.
    • Por la velocidad.
      Fish trae de fábrica muchas cosas que en zsh requerían plugins. Los plugins de zsh eran lentos y el inicio del shell pasaba de 3 segundos, mientras que Fish arranca mucho más rápido incluso con plugins.
    • La primera vez que creé un archivo fish_prompt.fish en el directorio correcto, escribí ahí una función fish_prompt e hice que imprimiera una cadena a la salida estándar para crear mi propio prompt del shell, casi borré zsh.
      Se vuelve difícil volver a la forma de meter de todo en $PS1 y esperar que salga bien. Recomiendo usarlo aunque sea unos días, porque permite ver cuáles de las cosas que dabas por sentadas son funciones específicas de cada shell. En el peor de los casos, decís “no es para mí” y volvés a bash/zsh o al shell que prefieras.
    • Me pasé de zsh a Fish hace unos años y las funciones son casi iguales, pero mi archivo de configuración de Fish tiene alrededor del 10% del tamaño de mi configuración de zsh.
      La mayoría de lo que quiero viene por defecto, y ahora solo uso un plugin: fzf.fish.
  • Es muy probable que uno de los shells más rápidos se vuelva todavía más rápido.
    Después de pasarme de zsh a Fish, mi productividad en la terminal aumentó mucho.

    • Yo no apostaría por eso.
      Según el enlace, en realidad no saben cómo será el rendimiento del port terminado. Los resultados iniciales son alentadores, pero en algunos casos perfectamente podría terminar siendo alrededor de un 20% más lento.
    • No creo que haya una diferencia de rendimiento tan grande entre C++ y Rust.
      Probablemente estén casi empatados y no haya un ganador claro.
    • Me pregunto en qué flujos de trabajo el rendimiento del shell se vuelve un cuello de botella.
      Normalmente lo veía más como código pegamento que delega el trabajo a otros lugares. Tal vez sea un tema de eficiencia de pipes, o de gente excéntrica que escribe programas completos en bash, pero Fish ofrece muchas mejoras de calidad de vida y me parece un poco curioso que la velocidad se mencione como ventaja central.
    • No creo que uno escriba y gestione tareas lo suficientemente rápido como para que importen las diferencias entre C, C++, Rust u otros lenguajes; me pregunto si Fish ofrece algo más.
  • Llevo un año usando Fish
    No me gusta que rompa la compatibilidad con los estándares hasta el punto de que algunos scripts como gvm y nvm no funcionen, pero trae incluidas todas las funciones que normalmente configuraba a mano en zsh. Después de intentar configurar zsh en varias máquinas y rendirme, cambié todo a Fish con la configuración predeterminada
    Ya funciona bien, así que no tengo muy claro qué se gana al portarlo a Rust. Si es por seguridad, me da la impresión de que cualquier cosa capaz de manipular Fish de forma maliciosa ya tendría que estar dentro del sistema

    • Como se mencionó en la discusión original sobre Rust, hay varias razones para pasarlo a Rust
      Principalmente tiene más que ver con atraer contribuidores y con agregar modos asíncronos/paralelos con los que los mantenedores puedan sentirse tranquilos
      [1] https://github.com/fish-shell/fish-shell/pull/9512
  • Fish es bueno
    Cambié de ZSH+Prezto a usar solo Fish, y no extraño nada; además es mucho más rápido. En los servidores todos tienen bash y sigo usando scripts de bash, pero para el trabajo cotidiano en la terminal, Fish es más que suficiente

  • Fish siempre me ha dado curiosidad, pero me frenaba que sea incompatible con POSIX
    Me pregunto si alguien puede compartir los problemas que ha tenido con esto y las formas de evitarlos

    • Fish no está pensado como reemplazo de scripts bash/shell, sino para usarse como shell interactivo, así que en la práctica el cumplimiento de POSIX no es un gran problema
      La desventaja es que requiere un pequeño cambio de contexto. Sobre todo si has usado bash/zsh toda la vida. Personalmente me resulta fácil distinguir entre cuando uso el shell como interfaz de usuario y cuando uso bash/sh como intérprete, pero puede que no sea intuitivo para todos
      Además, desde que dejé de usar un shell compatible con POSIX como shell diario, termino promoviendo más rápido a un lenguaje de propósito general los scripts que antes habría resuelto con bash
    • Los scripts de Bash/zsh simplemente se ejecutan con Bash/zsh: bash script.sh
      Cuando empecé a usar Fish, la incompatibilidad con POSIX me preocupaba, pero después de aprender un poco de la otra sintaxis y superarlo, creo que la sintaxis más sensata de Fish vale el esfuerzo. Ahora disfruto mucho más usar la terminal
      Además, el 90% del tiempo no hace falta mantener compatibilidad con POSIX, y hoy muchos scripts o extensiones también soportan Fish. En entornos corporativos sigo usando Bash/zsh, que son el estándar
  • Me pregunto por qué lo cambian a Rust
    ¿La base de código en C++ se estaba volviendo difícil de manejar?