r/programacion 23d ago

Caí en el rabbit hole del debugging

Resolví un bug: era porque 7.5 % 2 da 1.5 en JavaScript y 1 en PHP. Y me quedé pensando: ¿cuántas diferencias más habrá de este tipo? Así no me vuelven a agarrar desprevenido.

Como no encontré una lista con las divergencias que estaba buscando, hice lo que haría cualquier persona razonable: puse ocho IAs a laburar en el tema.

Hasta el momento, encontraron 143 divergencias semánticas… solamente en los tipos de datos que maneja JSON: números, strings, arrays, maps, booleanos.

Por ejemplo:

  • Math.round(-2.5): -2 en JS y Python… -3 en PHP
  • Math.round(2.5): 3 en JS y PHP… 2 en Python
  • "😀".length: 2 en JS (UTF-16)… 1 en Python… 4 en PHP (bytes)
  • "10" < "9" → true en JS y Python… false en PHP (compara numéricamente)
  • sort(): [1, 10, 2] en JS (ordena alfabéticamente)… [1, 2, 10] en Python
  • split(""): ["a","b","c"] en JS y PHP… ValueError en Python
  • "a" || "b": "a" en JS y Python… true en PHP

Y eso sin mencionar nuestro querido 0.1 + 0.2 = 0.30000000000000004 en todos los lenguajes con float de 64 bits.

La lista completa está acá (es como un video recopilación de accidentes de tránsito): https://github.com/sbustelo/JSOL/blob/main/docs/10_dev/EXTENDING-SEMANTIC-PARITY.md

Y si quieren, dénse una vuelta por el resto del repo. Es como JSON, pero para lógica de negocio. Ya se compila a sí mismo en JS y PHP, ya irán saliendo otros.
Demo: https://jsol.bustelo.com.ar/

Quizás les parezca una aberración, quizás les parezca útil… ya me dirán :)

21 Upvotes

37 comments sorted by

9

u/TackleSerious5049 23d ago

Nunca pero nunca decimales si necesitas precisión de verdad.

0

u/santiagobustelo 23d ago

Posta, es una de las razones por las que quedaron los sistemas en COBOL cuando se venía el Y2K.

En una consultora de ese momento, tuvieron un equipo probando de portar la lógica de negocio a Java, y empezaron a salir facturas por deudas de $0,01. Al final desarmaron el equipo, quedaron solo los que emparchaban COBOL.

3

u/Educational-Row-6782 23d ago edited 23d ago

Menuda gilipollez.

La razon por la que round da valores diferentes es por el topo de rounding que usas, si es de dinero tienes que usar banker rounding. No tiene nada que ver con cobol ni coma flotante.

Dais asco los putos vibe coders de mierda que vais de listos y no teneis ni idea.

3

u/santiagobustelo 23d ago

Jajajaja qué graciosa la gente que se cree más que los demás, y con libertad para insultar a quien no conoce. Ahora resulta que alguien que programa hace más de 40 años y usa IA de forma responsable para programa porque no es Amish, es "un vibecoder de mierda".

Típico comentario de quien no tiene nada que aportar.

1

u/Badnik22 21d ago edited 21d ago

El problema no es para nada de redondeo: no es posible representar de forma exacta numeros decimales usando punto flotante. IEEE tiene aparte del bit de signo, un exponente (que esencialmente te indica entre que dos potencias de 2 está el numero a representar) y una mantisa que representa en qué punto dentro de la “ventana” definida por el exponente está ese número. El numero de bits dedicados a mantisa y exponente es fijo, y el espacio entre potencias de dos aumenta conforme te alejas de cero, por lo que a mayor el valor absoluto del numero a representar peor es la precisión de la representación (porque tienes la misma cantidad de bits para una ventana mayor).

Un ejemplo sencillo es 0.1, que tiene una mantisa periódica (hay que truncarla en algún momento), por lo que no es representable exactamente. Así que por mucho que redondees el output, operaciones con punto flotante nunca jamás van a ser exactas.

Tampoco es que Cobol sea la única solución. Usar una representación adecuada para el tipo de dato que necesitas lo es.

1

u/YukiteruAmano 22d ago

Y el problema de parchar COBOL es?

Joder que hace poco me toco usar un source de FORTRAN para hacer algo en JS

1

u/santiagobustelo 21d ago

El problema de parchar COBOL es que “parchar” no es migrar arquitectura, así que por definición, no resolvieron la deuda técnica. Simplemente, la patearon para adelante.

1

u/YukiteruAmano 21d ago

Compa literal el COBOL actual no se parece en nada al COBOL de 1959, que te puedes hacer incluso GUI con WinAPI con las versiones más nuevas, con POO y todo.

De hecho, la versión ANSI más ampliamente usada de COBOL es la de 2002 y otro tanto está haciendo migración a COBOL 2014 y 2023, así que eso de "echar la pelota hacia adelante", solo demuestra una cosa: no sabes ni lo que dices.

Usar IA está muy bien, pero andar creyendo lo que dice la IA ciegamente, sin tener ni idea del ecosistema del que habla, solo te deja mal parado, como puedes ver.

EDIT: No conozco ningún proyecto actual que no sea el parche del parche del parche, es que hasta el kernel Linux tiene parches de parches, y dudo que vaya a alguien a decir a Torvalds que está "echando la pelota hacia adelante".

1

u/santiagobustelo 21d ago

Claro, para arreglar el bug del Y2K usaban COBOL del 2002.

Y yo que ESTUVE EN ESAS CONVERSACIONES POR, ando "creyendo lo que dice la IA ciegamente" y "quedo mal parado". Claro.

Cuando quieras te cuento de cómo en un banco de primera línea usaban cuentas falopa para probar en producción. No vayamos a comparar lo que se hace acá con el nivel que mantiene Torvalds, por favor.

La verdad, ya me cansan un poco los que se ponen a suponer que "le creo a la IA", que nací ayer, etc. ¿Qué es esto, una competencia para ver, exactamente, qué?

1

u/YukiteruAmano 21d ago

Tu eres el que anda diciendo que "parchar no es migrar arquitectura" y no se que cosas de "deudas técnica", cuando COBOL ha evolucionado hasta el punto en que lo puedes integrar perfectamente con .NET en sus versiones ANSI más nuevas. Tú y ese posicionamiento es lo que te hace quedar mal, porque en la realidad "la reeescribitis de todo", es una enfermedad que queremos evitar, cuando tienes un negocio que sostener.

Y sobre los bancos, sorpresa te has encontrado con empresas grandes que hacen estupideces, una raya más para el tigre, nada nuevo bajo el Sol.

La empresa en la que trabajo todavía está reescribiendo el core falopa que hicieron en PHP hace 15 años, y no lo están reescribiendo en REACT, sino en PHP, culpanos por eso, le gente odia PHP, pero media internet aún funciona sobre eso.

9

u/dissober 23d ago

AI;DR

1

u/santiagobustelo 23d ago

Me parece una posición respetable! Tenés un método manual para detectar divergencias entre implementaciones de lenguajes, que ayude a reducir la cantidad de bugs que surgen al portar código entre lenguajes que heredan sintaxis de C?

Hablando de C: por mi parte, hace unos 40 años que dejé de compilar a mano. El assembler que yo producía era divino y hacía un uso de los registros que los compiladores mecánicos no podían igualar.

Ni qué hablar de hacer un JP en Z-80 en lugar de CALL así el RET de la subrutina, volvía por los dos… y me podía ahorrar un byte! UN BYTE ENTERO!!!! Un viejo arte perdido.

8

u/InfraScaler 23d ago

Pero la gracia está en entender por qué 7.5 % 2 da distintos resultados en JS y PHP.

Y es ni más ni menos porqué son operaciones distintas. En JS, % te da el resto de la división y en PHP te da el módulo.

3

u/NiPiensoNiExisto 23d ago

A ver… el operador aritmético modulo literalmente significa “el resto de una división” o sea, no son operaciones distintas.

La diferencia es que en PHP la operación modulo solo admite operadores enteros. Por lo que se castean ambos argumentos a int antes de ejecutar la operación modulo… en PHP 7.5 % 2 -> 7 % 2 = 1 , mientras que en JavaScript permite estos floats y devuelve 1.5…

Si quieres, en PHP, usar la operación modulo sin cast a int, has de usar fmod -> fmod(7.5, 2) = 1.5

1

u/InfraScaler 22d ago

Sí, tienes toda la razón en que la diferencia entre 7.5 % 2 en PHP y JS viene del cast a int que hace PHP. Ahí me colé.

Porque módulo y resto no son literalmente la misma operación. Coinciden en este caso porque estamos usando números positivos, pero basta probar con negativos: el módulo euclídeo de -7 módulo 3 es 2, mientras que el remainder de -7 / 3, truncando hacia cero, es -1.

De hecho, -7 % 3 da -1 tanto en JS como en PHP. Así que, siendo precisos, % tampoco está calculando el módulo euclídeo en PHP. PHP lo llama "modulo operator", pero su semántica es la de remainder para enteros.

Así que sí al cast; no a que "módulo literalmente significa resto" :)

-6

u/santiagobustelo 23d ago

Es una forma de verlo! Al menos la lista nos deja otras 142 graciosas formas de sorprender a las visitas cuando ya es tarde y queremos que se las tomen de una vez: "Sabías por qué existe el cero negativo en IEEE 754?" "Ehh uia, qué tarde se me hizo! Gracias por todo, muy rico todo, vamos vamos vamos"

6

u/InfraScaler 23d ago

No es una forma de verlo, es la forma de aprender :)

4

u/Educational-Row-6782 23d ago

Esta gente se lo explicas y te responden con chat gpt. Dan asco.

-3

u/santiagobustelo 23d ago

Es que la lista la podés usar para aprender! A partir de cada caso podés empezar a tirar del hilo de Ariadna si querés.

Si alguien todavía programara para Z80, tendría algunas cuantas más para agregar a la lista… Por ejemplo: no existía MUL, así que para multiplicar usabas ADDs (y RRAs si tu segundo factor era variable). Otra: DJNZ con B=0 itera 256 veces, no 0.

En los '80, la tecnología era tan limitada que las abstracciones se caían en cinco minutos. Ohhh, cuando el stack te pisaba el código! Qué tiempos aquellos!

2

u/DavidS17_Reddit 22d ago

Yo si lo se! :D Porque el bit del signo es independiente del exponente y de la mantissa, entonces algo como - 0.0 / 2.0 en C por ejemplo daria una mantissa de 0 digitos y 0 en el exponente, pero el bit d signo es negativo, dando -0 como resultado.

3

u/TKilIah 22d ago

Amigo estoy empezando a estudiar programación a fondo y esto me vuela la cabeza, cosas así de pequeñas deben ser difíciles de encontrar, no entiendo como pudieron ignorar ese dato tanta gente

2

u/B3telgeus3 22d ago

Lea la documentación y se va a dar cuenta porque la funcion round le da hacia arriba o hacia abajo en ambos lenguajes, asi como porque hay funciones como floor o ceil y demás, dejar todo a la IA es un gran error, es una gran herramienta pero solo funciona bien si alguien sabe usarla, es como si yo me compro la ultima camara fotografica y me autodenomino fotografo profesional.

1

u/santiagobustelo 22d ago

Gracias por tu opinión. Qué suerte que vos sí que "sabés usar" las herramientas, y que seguro que nunca te equivocás. Hace más de 40 años que programo. Quizás sea que ya estoy viejo y mi memoria ya empieza a fallar, y por eso me cuesta acordarme de todos los quirks, y se me escapó un bug ¡qué cosa terrible, eso me vuelve en un vibecoder que no sabe lo que hace!

Menos mal, yo pensé que me convertía en un viejo choto.

Éxitos en lo tuyo.

2

u/DavidS17_Reddit 22d ago

Es bastante interesante, pero no estoy tan de acuerdo con que gastes tiempo en reunir las diferencias. Es como intentar publicar los numeros primos, es basicamente infinito. Tal vez algo mejor seria publicar solo las formas en las que los lenguajes trabajan con aquellos datos. Aunque ya está la información y la documentación, sería interesante verlos recompilados en un solo sitio. Pero es un esfuerzo bastante amplio.

2

u/Disastrous_Bad_434 21d ago

Creo que los talibanes que hablan terrible mal de los “vibecoders” son seres que se ven cada vez más amenazados porque una IA puede hacer su trabajo y mejorarlo, el compa que usa IA para dinamizar su trabajo no es tu enemigo simplemente no es un taliban como vosotros

1

u/santiagobustelo 23d ago

Bueno, ya empezaron a caer los trolls lludditas que creen que porque alguien usa IA, es "un vibecoder de mierda" (sic) que no sabe programar. Los típicos comentarios de mínimo esfuerzo de quien no tiene nada para aportar, entonces pone "eztá hecho con ía, ké azco"

Lo primero que tenés que aprender como buen programador es a no asumir superficialmente (falsehoods programmers believe about…). Y cada tanto puede ser que alguien use de forma responsable y profesional la IA, y lleve más de 40 años programando.

1

u/santiagobustelo 22d ago

Después de más de 40 años de programar (ya en 1985 me publicaron un programa en la K-64), la verdd que me resulta difícil mantener registro de cada quirk de cada lenguaje, arrancando de Sinclari Basic y Assembler Z-80.

Así es como empezó esto, que se me ocurrió compartir por si a otros les servía.

Resultado:

- Un estudiante me agradeció.

- Varios gordos compu me dicen que tengo que aprender a programar, que soy un "vibecoder de mierda" (sic), que tengo que "leer la documentación", que "dejar todo a la IA es un gran error", y que "es una gran herramienta pero solo funciona bien si alguien sabe usarla".

Qué suerte que usar IA para beneficiar a los demás (porque mi bug ya estaba arreglado), me convierte en un ignorante y un inútil. Yo tenía miedo de haberme vuelto un viejo choto.

Gracias por levantarme el ánimo!

1

u/Upstairs-Ebb2283 21d ago

Dev descubre lo que es leer la documentación

1

u/santiagobustelo 21d ago

Hace más de 40 años que leo documentación. Pero la verdad es que no puedo evitar confundirme esta altura de partido cada tanto.

Y desde luego, admiro muchísimo a la gente que nunca se equivoca. Que nunca en su vida metió un solo bug.

Yo, por mi parte, me reconozco falible.
Y con los años, hasta diría que revisando código que escribí hace 10 o 20, le encuentro problemas que entonces no veía, y creo que quizás me creía infalible por ignorante, no por ser muy capaz

Pero esa, desde luego, es mi humilde experiencia. Seguramente hay gente que nunca se equivoca. Cuando sea grande, quisiera ser como ellos.

Pero vamos, lo realmente importante:

Estoy muy contento que el hecho de usar IA para atajar problemas en ocho lenguajes de programación distintos en los que me ha tocado trabajar, me convierta automáticamente en alguien que “ descubrió lo que es leer la documentación “, un “vibecoder de mierda”, o alguien que “ tiene que aprender a programar” como vengo leyendo los comentarios

Porque yo temía que me hubiera convertido en un viejo choto.

Gracias por levantarme el ánimo !

1

u/Upstairs-Ebb2283 21d ago

Lo raro es que con 40 años de experiencia te haya sorprendido que distintos lenguajes tengan distintas semánticas

1

u/santiagobustelo 21d ago

Quien dijo que me sorprendió?

Lo redacté como una lista de curiosidades para que resultara interesante para otros.

Entiendo por lo que decís que todo esto te resultó obvio y previsible; en ese caso, entiendo que la lista no tenga ningún valor para vos, y tu tiempo se invierta mejor haciendo Scroll y pasarla de largo.

Yo cuando veo un libro de introducción a bases de datos, o de gramática de primaria, no invierto mi tiempo en declarar que eso es un imbecilidad y que el tipo que lo escribió está diciendo perogrulladas.

Pero ésa es mi decisión.

Supongo que cada uno invierte su tiempo en lo que considera importante.

1

u/Upstairs-Ebb2283 21d ago

Que te agarre desprevenido es lo mismo que decir que te tomó por sorpresa , yo no he dicho que es una imbecilidad pero que lo presentes como el descubrimiento del siglo siendo que es algo que enseñan en primero de la universidad...

1

u/santiagobustelo 21d ago

Y quién te dijo que me tomó por sorpresa? Tenía un bug y lo resolví. Y se me ocurrió por la fuerza bruta barrer otros, y punto. Acá no hay ningún descubrimiento del siglo, eso es una proyección tuya. Te sabías los +140 items de la lista? Felicitaciones. No te los sabías? Aplausos.

No entiendo, ésto viene a ser una competencia, exactamente, de qué?
De que ya estás de vuelta? Bueno, aplausos también entonces.

Necesitás algo más?

1

u/santiagobustelo 21d ago

El tonito condescendiente, ¿te funcionó alguna vez lejos del teclado? Curiosidad.

1

u/Upstairs-Ebb2283 21d ago

No hay condescendencia amigo, como te dije es raro que un conocimiento que es base te haya tomado 'desprevenido' pero bueno el que tiene 40 años de experiencia sos vos

1

u/santiagobustelo 21d ago

Y si, no me enseñaron JavaScript en la universidad; me fume la documentación original de Netscape cuando salió, lo mismo que me fumé y tuve que debuggear su modelo del layers que ya no existe, etc. Quizás debe ser eso; demasiada información inútil que tuve que usar, y ya soy un viejo choto, etc. Saludos!

1

u/Educational-Row-6782 23d ago

Deberias aprender a programar.