@iamemhn

EM Hernández-Novich

Ask @iamemhn

Sort by:

LatestTop

Previous

Profesor, estoy haciendo una base de datos en PostgreSQL y tengo la duda que tipo de datos usar para almacenar las fotos de los usuarios. Por lo que leí asumo que el bytea hex debe ser igual a blob. Estoy en lo correcto?

El estándar SQL incluye Binary Large Objects, usualmente llamados BLOBs. PostgreSQL tiene dos estrategias para almacenar BLOBs: si el objeto binario que estás manejando es suficientemente pequeño para ser manejado como un todo, usas BYTEA; si es muy grande, usas Pg Large Objects.
Si «fotos de los usuarios» son «fotos carné» para avatar, eso entra en la categoría BYTEA. Si son «cualquier foto que se le ocurra al usuario, sin límite de tamaño», probablemente son LO.
Los BYTEA se manejan a través de SQL tradicional, como una columna más. Tienes que ser cuidadoso en almacenar el tipo MIME apropiado, para que la aplicación cliente sepa que hacer con los bytes.
Los LO se almacenan asociados a cada fila, pero fuera de la fila, y para manipularlos necesitas funciones PG especiales, que están diseñadas para hacer streaming. Puedes almacenar MP3 y video digital en la base de datos sin afectar su desempeño, y entregarlas muy eficientemente a sockets de aplicaciones cliente cuando las requieran.

View more

Profesor, me pidieron guardar certificados digitales de usuarios en una base de datos PostgreSQL. ¿Eso tiene sentido? ¿No es mejor guardarlos en el sistema de archivos? Son sólo los certificados, no están las llaves privadas. Gracias por sus consejos. Le deseo que esté sano y salvo con su familia.

No hay ningún problema en guardar la parte pública de los certificados digitales X.509 dentro de la base de datos. PostgreSQL siempre ha tenido la habilidad de almacenar contenido arbitrario en la base de datos (archivos, imágenes, audio, video) de manera eficiente y sin afectar el desempeño.
Tener archivos fuera de la base de datos, pero relacionados con filas de la base de datos, agrega complejidad innecesaria, casi toda para manejar casos de falla adicionales, porque tienes que «reinventar» la rueda (integridad).
Dependiendo del caso de uso, hay algunas cosas astutas que puedes hacer. Por ejemplo, es natural que tengas que almacenar el certificado como un todo en formato PEM. Podrías tener un TRIGGER ON INSERT/UPDATE para que extraiga campos relevantes del certificado (por ejemplo fechas de validez) y las ponga en columnas adicionales, o bien verificar que el nombre certificado coincide con el usuario al que se lo estás asociando.
Extraer el certificado como un todo al sistema de archivo o a una función PL/pgSQL es un simple SELECT. Usarlos para comprobar una firma digital es más complicado, y probablemente tengas que escribir tu propia extensión para hacerlo a tavés de OpenSSL o GnuTLS via C.
Gracias por tus buenos deseos.

View more

¿Qué opina de Rascal como lenguaje?

Es interpretado, y el interpretador está escrito en Java. O bien puedes generar clases en Java y correrlas en Java. En pleno siglo XXI. Paso y gano.

Related users

Cuál es su opinón con respecto a rust?

https://ask.fm/iamemhn/answers/152326036052
No ha cambiado mucho.
Si necesitas escribir programas imperativos y no puedes darte el lujo del consumo de memoria y la potencial interferencia de recolección de basura, entonces Rust es bastante mejor que usa Golang o C en términos de asistencia al programador. El sistema de tipos de Rust es bastante mejor que el de Golang, y como no provee manejo automático de memoria, el ambiente de ejecución es más pequeño y más rápido. El manejo de memoria manual con el concepto de «propiedad» de un valor según su «tiempo de vida», que además es verificado por el compilador, es posiblemente lo más complejo para un programador que nunca ha visto algo similar ni ha estudiado cómo funciona un lenguaje de programación internamente.
El compilador a mejorado mucho tanto en velocidad como en calidad del código que genera. La librería estándar todavía tiene camino por recorrer, aunque no es tan caótica como las de Golang o C. El manejo de dependencias es definitivamente más civilizado que lo que hace Golang o usar `autoconf/automake` con C. Todavía tiene camino por recorrer, con la ventaja que sus diseñadores y desarrolladores tienen motivaciones más generosas que las de Golang, y menos conservadoras que las de C.
Si el objetivo es desempeño, garantías estáticas (razonables) sobre el tamaño y consumo de memoria al ejecutar, Rust es una alternativa más moderna que las opciones de Golang o C. Si no estás sujeto a restricciones de tiempo real o limitaciones en consumo de memoria, no quisiera ninguno de esos tres, sino un lenguaje moderno de más alto nivel, como Haskell.

View more

Me extraña que los servidores del dominio gtld-servers.net tampoco tienen DNSSEC habilitado. Esto no es una falla en la cadena de confianza porque cuando vas a buscar las llaves puedes ir a un grupo de servidores impostores?

No.
La cadena de confianza se verifica desde la raíz hasta el dominio que usa DNSSEC.
Para verificar el dominio `example.link` que usa DNSSEC, la cadena de confianza se verifica:
* Las KSK de `.` se dan por buenas porque vienen como parte del software para DNS y se puede descargar por vía segura para actualizarlo.
* En raíz `.` se buscan los DS para `.link` y deben coincidir con los hashes de los DNSKEY KSK publicados para `.link` en uso para firmar `.link`
* En `.link` se buscan los DS para `example.link` y deben coincidir con los hashes de los DNSKEY KSK publicados para `example.link` en uso para firmar `example.link`
* Los RR en `example.link` firmados por DNSKEY ZSK a su vez firmados por DNSKEY KSK se consideran válidos.
Si `gtld-servers.net` no está usando DNSSEC, no afecta la verificación de la cadena de confianza de otros dominios. Sólo afecta los *subdominios* bajo `gtld-servers.net`.
Revisa el concepto de «Chain of Trust» en esta presentación o en la documentación DNSSEC de BIND9 para más detalles.
https://www.lacnic.net/innovaportal/file/3135/1/dnssec_intro-mvergara.pdf

View more

¿Alguna idea acerca de por que ni google, ni amazon, ni microsoft usan DNSSEC para sus dominios de internet?

Un error de configuración en la gestión de llaves o en la cadena de delegación, bien sea en la propia zona, o en la zona superior, hace que la zona firmada no sea válida, criptográficamente hablando. Cuando una zona anuncia DNSSEC y no es válida, los resolvers no confiarán en las respuestas autoridad, ignorándolas. Eso hace que el dominio sea completamente invisible hasta que el error sea corregido. «Invisible» como «el dominio no existe, no puedes enviarle correo, no puedes acceder a sus páginas web, no puedes obtener nada en los subdominios» invisible. Un error DNSSEC puede tomar mucho tiempo en corregirse de raíz, y se alivien sus consecuencias, dependiendo de los TTL y la magnitud de la metida de pata.
Hace dos semanas, Microsoft anunció que la plataforma Office 365 tiene un plan para introducir DNSSEC y DANE. De ese modo los dominios de *terceros* allí hospedados, van a comenzar a tener mejores características en lo que a «servicio de correo moderno» refiere. Eso es un paso interesante, porque eran los que estaban más atrasados. Google y Amazon tienen instrucciones y documentación para que los *terceros* que quieran, puedan usar DNSSEC sobre las respectivas nubes. Pero ninguno tiene ni siquiera DNSKEYs en sus zonas propias.
Por supuesto que no tengo toda la información que esas organizaciones manejan, ni conozco sus infraestructuras, así que solamente puedo especular. Podría haber otras justificaciones que no alcanzo a ver porque Nunca es Fácil®.
Mi conjetura es que han cosiderado el riesgo a que su dominio sea invisible resulte un precio demasiado caro, en reputación y en dinero, por un error en la operación. No estoy seguro si se justifica esa precaución hoy en día, dado el estado del software DNS moderno (BIND9 y PowerDNS) en cuanto a la gestión automática de casi todo lo frecuente, y que las infrecuentes interacciones con la zona superior usualmente tienen múltiples verificaciones por adultos responsables.
Me parecería rebuscado que la justificacion fuera algo así como que las zonas firmadas son más grandes, o que firmar las zonas requiere mucho CPU, incluso si el material criptográfico estuviera en HSMs que son bastante más lentos de acceder. Si hay algo que esas organizaciones tienen es dinero para pagar el hardware necesario para mitigar esas condiciones.
Ahí es donde miras a nasa.gov, irs.gov, cia.gov, fbi.gov, por nombrar algunos que operan con DNSSEC y no tienen ese miedo. Y mira que irs.gov es la empresa de cobranza más efectiva de la humanidad :-)

View more

Profe... He pensado en estudiar Informática online (en alguna instiitución pública) porque tengo un familiar a quien cuido la mayor parte del tiempo. Me gustaría saber qué opina sobre este tipo de alternativa (estudios a distancia). Gracias

Lo más importante para recibir educación, es tener el deseo de aprender. Si tienes deseo de aprender, irás más allá de lo que te digan o asignen, en persona o remotamente.
La experiencia de aula y cooperación con otros estudiantes, enseña cosas que van más allá de los contenidos, y que son importantísimas para ser un informático competente. En informática se trabaja con otros y para otros, así que saber trabajar en equipo y comunicarse efectivamente es crucial. Que nadie te diga lo contrario. Lee y escribe, perfecciona tus idiomas, al menos español e inglés.
La oportunidad de interactuar con un instructor que sea realmente experto en el tema y tenga la capacidad de despertar tu curiosidad, es posiblemente lo más subvalorado de la educación (formal o informal). Un aula o un video con un instructor que sólo repite lo que sabe, sin darle contexto concreto, ni retar a los estudiantes a cambiar sus puntos de vista, con suerte produce seguidores de recetas, aburridos, y con simple interés utilitario. Hay gente que quiere eso, lo recibe, y es feliz -- pregúntate si quieres eso, como alumno, o como instructor, cada vez que acometas el proceso de adquirir conocimientos y decidir si lo que recibes cumple o no.
Esperar a que el instructor, en persona o remotamente, te diga «todo lo que tienes que saber y hacer», no te hará aprender nada. Lo que hace falta es que esa comunicación sea tal que te motive a preguntar, explorar, y experimentar. Esa es la diferencia entre el instructor y el profesor.
Así que, adelante en tu esfuerzo de aprendizaje por el canal que sea más adecuado a tus circunstancias, sin perder de vista que la responsabilidad de aprender es exclusivamente tuya,

View more

How should a Haskell developer write code in order to create predictable access patterns of memory to be more sympathetic with the hardware and prefetchers in order to don't pay the cost of moving cache lines from main memory to L1 or L2?

Your question suggests Haskell's execution model resembles that of any other imperative language. This is not the case so your question could be answered with «Mu».
Thanks to having immutable state, GHC inlines code more often and aggressively than your regular imperative language compiler does. This makes the executable have less loops and function calls overall. This makes it move way less cache lines from the get go.
Again, thanks to having immutable state and being based on function composition and application, GHC can simplify your code in many ways using math -- a sequence of function applications or composition can be fused in a single faster/smaller one. For GHC to be able to do this, you should use fmap (from Functor), fold* (from Foldable), and avoid explicit recursion whenever possible. Model your code using Monoid, Functor, Applicative, Foldable, and Traversable, and let the compiler fuse those computation so they will end up in tight loops.
When interleaving pure code with effects, try to use the smallest Monad stack possible. Learn to combine them, and to reorder your stack to achieve minimal lifting requirements.
Use GHC's profiling tools to figure out where in your code you need to improve. Improvements usually mean: using better types (don't use an Integer, when a Word64 would do; don't use Int when an enumeration would do, so on and so forth); adding strictures; choosing appropriate functional algorithms (you don't use Quicksort, you use Arrays only for dynamic programming, you use the specialized functional data types instead of the regular imperative ones, you don't «simulate» imperative algorithms on top of IO).
GHC profiling tools for CPU, memory, and concurrency, are your best friends. Bear in mind that most of Haskell values are handled on the heap, so a predictable pattern is quite hard to achieve. However, you're objective is for the runtime to be able to immediately reuse the heap block just recovered by garbage collection. You'll do that if you use abstraction and fusion, instead of plain recursion.
Lather, rinse, repeat.

View more

Desde que vi clase con usted, me han interesado los lenguajes funcionales. En el área que me interesa, videojuegos he notado que no hay en uso ninguno en gran escala. Mi pregunta es por qué no han tenido mucho éxito los funcionales en las áreas de soft y hard real-time en consumer grade o embebidos?

Haskell es una opción mala para correr sobre dispositivos con capacidad reducida y restricciones importantes de tiempo de respuesta.
El compilador de cualquier lenguaje de programación agrega un ambiente de ejecución «runtime environment» a todo programa ejecutable. Todos los ambientes de ejecución son distintos, más o menos complicados dependiendo de las capacidades del lenguaje. y hasta reemplazables en algunos lenguajes (en C puedes cambiar malloc por alloca). Decir que los lenguajes A y B «son lo mismo» porque ambos tienen «recolección de basura» o no, es una afirmación muy simplista. El recolector de basura de Haskell es muy diferente (y superior) al típico de Java o Python (que son diferentes entre si), y que el de JavaScript. El punto es que todo lenguaje tiene que tener algo como ambiente de ejecución, sea simple o complejo, y eso influye en su aplicabilidad a una plataforma particular.
En un lenguaje como Haskell, este ambiente de ejecución incluye reductor de thunks, manejador de memoria, recolector de basura, y sistema de hilos, entre otras cosas. Ese ambiente de ejecución, y el de cualquier otro lenguaje de suficiente nivel, resulta muy oneroso tanto en memoria como en cómputo, para una plataforma que por definición es restringida (como un Arduino o un Cortex M).
El compilador de Haskell produce código ejecutable muy eficiente, gracias a varias técnicas de optimización especializadas, una de las cuales es el inlining: en vez de hacer llamadas a funciones, se transforma el cuerpo de la función para insertarlo en el camino necesario. Esto conduce a programas muy eficientes, con menos fallas de caché, pero que ocupan más memoria. Otra vez, esto hace díficil usarlo en una plataforma con restricciones de memoria.
Sin embargo, hay librerías en Haskell que proveen DSLs (Domain Specific Languages,como atom, frp-arduino, arduino-copilot) que te permiten escribir a muy alto nivel en Haskell aprovechando el sistema de tipos, usar el DSL para expresar las restricciones de uso y concurrencia de la plataforma final, y luego generar código en C susceptible de ser usado en el sistema embebido. El DSL está construido de manera tal que, gracias al sistema de tipos superior de Haskell, las invariantes de bajo nivel son sencillas de expresar y *verificar*, antes de simplemente escupir el código C necesario.
Los GPU son embebidos especialísimos. Si quieres hacer programación vectorizada de alto desempeño para cálculo numérico o «estadística aplicada moderna», Haskell tiene un DSL que aprovecha los GPU para las operaciones y genera el código requerido CUDA u OpenCL.
¡Pero aún hay más! ¿Ṁúsica? Hay un DSL para expresar música (notas, acordes, tiempos, instrumentos) y generar eventos MIDI.
La idea es usar un lenguaje expresivo con un sistema de tipos poderoso, para asegurar que las operaciones de bajo nivel «tienen sentido», antes de generar el código.
Traductores y compiladores, programas que generan programas. Ahí está el arte.

View more

Liked by: Marcos Mora

que seria mejor para el crud? 1. una function o sp o 2. dejar que PostgREST se encargue de eso al exponer tablas y demas

Depende lo que necesite tu CRUD. Uno dice «CRUD» alegremente, y resulta que las inserciones son más complicadas, porque «Nunca es Fácil®»
Si realmente tus inserciones son meros INSERT porque *todos* los errores están detectados con un correcto uso de tipos de datos (nada de TEXT de pobre) y triggers, entonces es suficiente con PostgREST. Mismo caso para UPDATES y DELETES.
En el momento en que un INSERT o UPDATE requiere hacer cuentas o verificaciones procedurales multi-tabla o multi-operación, ponlas en un procedimiento almacenado.
Liked by: eliecercedano

Profesor, estoy intentando hacer una tabla con time travel en PostgreSQL como usted recomendó pero cuando intento crear la clave primaria me dice que el campo "valido_hasta" no puede ser NULL. Tampoco con valor por defecto de '0000-00-00 00:00'. ¿Qué me faltó o entendí mal? Gracias profe. Miguel

Una clave primaria no puede tener NULL. Sospecho que el problema es haber declarado una combinación de campos de la tabla como PRIMARI KEY, incluyendo el de fecha «hasta». Sin embargo, para mi solución habitual de «time travel» sólo hace falta una restricción de unicidad con un índice UNIQUE. Los índices UNIQUE si pueden tener campos NULL.
PostgreSQL hace lo correcto al rechazar el valor 0000-00-00 00:00 porque es una fecha inválida. No hay año cero, mes cero, ni día cero -- quejas al Vaticano que es el diseñador del calendario más recientemente en uso. No faltará quien diga que MySQL acepta ese valor como fecha, y eso es evidencia adicional que se trata de una fecha inválida.

Tengo la duda si es mejor Tener un repositorio de código (p.ej. GIT) por componente de un sistema o uno solo con todos los componentes del sistema? Cual sería su recomendación basado en la cantidad de programadores (1 / varios)? Gracias adelantadas!

No puedo decir que una cosa sea mejor que la otra, pues ambos tienen fortalezas y debilidades en escenarios variados.
Un «monorepositorio» aporta mucha coherencia, porque todo el trabajo está junto, y definitivamente simplifica el flujo de trabajo, porque compilar, probar, desplegar, o respaldar, se hace con un sólo juego de archivos. Al mismo tiempo, tienes el problema de que se reduce el aislamiento pues cualquiera puede cambiar cualquier cosa (incluso cuando hay «procesos» para impedirlo). Manejar conflictos en este escenario requiere mucha disciplina en el uso del VCS. Por último, a medida que crezca el repositorio y el equipo, las operaciones del VCS y el flujo de trabajo se harán cada vez más lentos.
Tener múltiples repositorios maximiza el aislamiento entre componentes que sean estrictamente independientes, siempre que el equipo sepa mantener los componentes independientes. También se reduce el tiempo de resolver conflictos y compilar componentes, precisamente por estar separados. Al mismo tiempo, es terrible intentar cualquier refactorización global si ésta afecta más de un componente independiente. Encima, el flujo de trabajo va a ser más complejo (y frágil) porque tienes que integrar repositorios disjuntos.
Quizás a un equipo pequeño le convenga comenzar con un repositorio único y comenzar a separar componentes a medida que se hacen tan estables que rara vez son modificados fundamentalmente. No creo poder decirte cuál es la cantidad de miembros en el equipo que sería el umbral para comenzar a separar en varios repositorios.
Transversal a todo ésto está el lenguaje de programación que hayas escogido. Hay lenguajes (algunos de ellos «modernos» y «populares») cuyas herramientas no están concebidas para trabajar con múltiples repositorios disjuntos, y otros que lo permiten después de mucho rechinar de dientes con variables de ambiente y toda suerte de accesorios. Entonces, si te toca un lenguaje que te «obliga» a usar monorepositorio, no tienes nada más que hacer.

View more

¿Qué es mejor, lenguajes con tipos estáticos o con tipos dinámicos? ¿Cuál es la ventaja y desventaja de uno y otro?

Cuando cometes un error en tu programa, siempre (¡siempre!) va a ser un error de tipos. Lo único que cambia es quién va a reportar el error: el usuario final, las pruebas de control de calidad, o el compilador.
Sería muy audaz de mi parte, y carente de profesionalismo, despreciar más de 40 años de investigación y avances en lenguajes de programación, para empujarle todos los errores de tipos a las pruebas de control o, peor aún, al usuario final.
Así que prefiero un sistema de tipos estáticos (como el de Haskell, no como el de Java, C++, Golang) porque el verificador de tipos del compilador es bastante más inteligente y observador que mi «intuición» del programa que estoy escribiendo. Mientras más completo es el sistema de tipos, más fácil resulta modelar el problema, más dificil resulta mezclar Strings con Strings, y sólo tengo que escribir pruebas relevantes al problema, y no a la implementación.
Lo mismo aplica al comparar un sistema de tipos estricto y parcialmente estático, como el de PostgreSQL, y la aproximación al almacenamiento de Strings que tiene MySQL. Prefiero la protección del primero, antes que las curiosidades del segundo.
El argumento de que usar tipos dinámicos permite «programar más rápido» me parece débil, considerando que te ves obligado a programar más pruebas, iterar varias veces, e incluso agregar artefactos para «reportar cualquier error extraño que no imaginamos». Mi experiencia con ambos enfoques me hace preferir al compilador de Haskell y escribir reconocedores (parses) estrictos, antes que decenas de miles de pruebas para ver donde mezclaron String con String mucho peor de lo que uno se imagina, o cual clave se les olvidó poner y no lo habíamos tomado en cuenta.
Dicho todo ésto, hay problemas para los cuales el sistema dinámico de tipos de Prolog o de Scheme, me ayudan a expresar más rápido un prototipo, y posiblemente una solución. Para ese tipo de problemas, son perfectos.
Las «soluciones» aproximadas como anotaciones de tipos (para darte una pista) o verificadores estáticos separados del compilador, me parecen más una excusa del obrero que no quiere cambiar su alicate, destornilladores (dos, exactamente dos), y dientes, por una caja de herramientas completa.
Sigo disfrutando de la expresividad y posibilidad de construir sistemas y meta-sistemas con Scheme, Prolog, y Perl, pero no puedo ignorar que es mucho más productivo y mejora la confianza en el entregable, cuando uso Haskell. Y no hablemos del desempeño final comparado con los «estáticos» clásicos o de moda.
En todo caso, aprende todos los lenguajes que puedas, y compara cuánto te cuesta construir software sobre el cual puedas razonar concretamente, y al mismo tiempo mantener o mejorar con menor esfuerzo, sin que sean los usuarios, ni las pruebas, los que te reporten la mayoría de los errores.

View more

Como haría un query recurrente de agregación en una ventana temporal utilizando PostgreSQL ? Me recomiendan utilizar InfluxDB pero me niego a pensar que no se puede hacer con postgre.

No entiendo la pregunta del todo.
Si escribes «ventana temporal» queriendo decir «serie de tiempo», lo primero es explorar Windows Functions (§ 3.5 del manual) y si eso no es lo que buscas o no es suficiente, probar con algo como la extensión TimescaleDB para PostgreSQL que asiste en el particionamiento automático tanto de datos como de la consulta.

Cuando se dio cueta que querias ser computista o cual fue el hecho o circunstancia que lo engancho con la computación?

Hice un curso de programación en Basic para Apple ][ en 1982 y después de terminar los ejercicios, me puse a escribir programas para resolver las tareas de matemática de tercer año de bachillerato (no lo sabía, pero era un flojo eficiente).
Visto mi entusiasmo, me dijeron que investigara para tener una computadora en la casa. Originalmente porque mi padre me enseñó a escribir a máquina correctamente a los 10 años, así que iba a ser más eficiente así que con mi Olivetti mecánica., Por supuesto escogí una computadora completamente diferente a la que tenían todos mis conocidos, simplemente porque tenía «Lenguaje de Máquina» y más «conectores». Era una Kaypro 4 (1984) con CP/M, BASIC interpretado y compilado, y lo que haría la diferencia, un ensamblador y desensamblador para Z80 (<3).
A los cuatro meses había desensamblado el BIOS para agregarle parches para «cosas», en particular poder imprimir apaisado en la impresora de matriz de puntos. Ese fue el día que dije «la máquina me obedece si no le pido estupideces, quiero dedicarme a esto».
Tenía poco menos de quince años.

View more

Maestro: leí que EXT4 o XFS usando sigues. ¿Por qué no se ha montado en el avión de ZFS?

No me gusta la licencia de ZFS y encima hay que hacer unas cuantas cosas para poder usarlo en Debian.
Con LVM y ext4 o XFS tengo suficiente. Las pruebas de desempeño de PostgreSQL sobre estos sistemas de archivo muestran que el esfuerzo adicional para tener ZFS no compensa los beneficios adicionales de desempeño.

Aparte de la diferencia de desempeño, ¿cuál es la diferencia entre usar Haskell compilado e interpretado?

Si con «interpretado» te refieres a usar cosas como
#!/usr/bin/runghc
main = putStrLn "hello world"
la diferencia fundamental es velocidad de ejecución, que es notable en cualquier programa no trivial. Tengo muchos scripts utilitarios escritos así, porque son más rápidos de escribir y de ejecutar que su equivalente en Perl o Shell. Como se usan poco y «una sola vez», me basta.
Si con «interpretado» te refieres a usar `ghci en forma interactiva`, hay diferencias mínimas que tienen que ver con inferencia de tipos cuando no hay firmas explícitas, porque `ghci` tiene menos información disponible que el compilador. Esas diferencias rara vez te afectan. Además, `ghci` está pensado para uso interactivo (`runghc` no), entonces tiene comodidades como invocar editores, adaptar el shell con comandos adicionales, y facilidad para activar/desactivar módulos. La ejecución es bastante más lenta.
Una de las herramientas más convenientes para desarrollo es `ghcid`. Es un «interpretador» que está en modo «recarga y recompila todo cada vez que haya un cambio» -- tienes reacción inmediata cada vez que metes la pata. Si combinas eso con usar type holes, es como si el compilador es el que programa y tú sólo estás para completar los blancos. Es suficientemente rápido para el ciclo de desarrollo.
Para poder usar las capacidades de análisis de desempeño (profiling) y trabajo concurrente, necesitas compilar, no sólo tu código, sino las librerías involucradas.

View more

que recursos recomienda para aprender sobre bases de datos? para un "no tech"

Creo que todo el mundo se beneficia de entender unos cuantos detalles técnicos sobre la operación de bases de datos relacionales. Por un lado, para no ser de los que creen que «todo se puede hacer» o «todo es fácil» o «¿cuán complicado puede ser?» -- en particular, cuando aquello en que están pensando es una audacia estólida.
Así que, es de mucha utilidad menos aprender el modelo relacional y las cosas que se expresan con SQL. Más aún, para algunos usuarios en posiciones tácticas o estratégicas, saber SQL les permite hacer consultas para análisis de negocios, mucho mejores que «traigame todos los datos a la hoja de cálculo». Son buenas referencias:
«Relational Database Design and Implementation», Harrington
«Learning SQL», Beaulieu
Y para practicar, leerse el Prefacio y Secciones I y II de
https://www.postgresql.org/docs/12/index.html
para luego hacer https://pgexercises.com/
Cosas como bases de datos clave-valor o no-relacionales, aunque son «populares», muy rara vez son la solución adecuada para los problemas concretos. Llegas más lejos con PostgreSQL que con cualquiera de las demás.

View more

Volvieron los peronchos.

El hombre es el único animal que tropieza dos veces con la misma piedra. O con el mismo animal.

es seguro utilizar set role para correr functiones (u otra cosa que corresponda y necesite) en PostgreSQL? gracias

Si necesitas que una función tenga temporalmente los privilegios del dueño de alguna de las tablas manipuladas, lo conveniente es crear la función con dicho usuario haciendo SECURITY DEFINER.
Más aún esa es la técnica recomendada para controlar el acceso parcial a tablas con información privilegiada. Exite un role P que tiene privilegios sobre la tabla, y ese mismo usuario crea funciones para agregar/cambiar/consultar los datos relevantes. Esas funciones son creadas con SECURITY DEFINER, de modo que cualquier otro usuario U las pueda ejecutar. Cuando ejecutan, tendrán los privilegios de P.
Cosas como darle todos los roles a todos los usuarios, y luego hacer SET ROLE para que usen el que les convenga, es casi lo mismo que tener un sólo usuario que haga todo. No es conveniente.
Cada usuario real debe tener un usuario diferente, con los privilegios mínimos para hacer su trabajo. Si necesita acceder a tablas con información parcialmente privilegiada (por ejemplo, una tabla de empleados donde NO puede ver el sueldo), entonces se le provee con una vista o con una función que pueda ejecutar, pero que ejecute con los privilegios del dueño de la tabla a modificar.

View more

$ ghci Prelude> 1.18 * 10 Why the result is not 11.8?

Alberto Mijares
Los números en punto flotante no son como los números reales de papel y lápiz. Son aproximaciones discretas, con precisión limitada, y usando base 2. La operación «obvia» que uno tiene en mente de «mover el decimal» no funciona así, porque no es la operación que se hace internamente.
Otros lenguajes decidieron redondear después de cierta cantidad de cifras significativas, y muestran el 11.8. Haskell decide mostrar todas las cifras significativas. Las dos decisiones son igual de válidas. Quizás 1.18 * 10 no «funciona» en Haskell y en otros lenguajes si. Al mismo tiempo, es posible encontrar un ejemplo que funcione en Haskell y en otros lenguajes no.
Los números en punto flotante no son como los números reales y hay que ser muy cuidadoso cuando se usan. Por eso existen tratados sobre Cálculo Numérico, y lenguajes específicamente diseñados para ese tipo de cosas.
Es pertinente revisar
http://www.lahey.com/float.htm
y el intimidante, pero no menos correcto y necesario
https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
Sigue las recomendaciones allí descritas. Si necesitas aún más precisión y «protección» ante la inherente dificultad del cálculo numérico, prueba usar Julia o Fortran.

View more

¿Es posible establecer un servidor web con ABA CANTV casero? ¿O estoy obligado a contratar un plan de internet empresarial? Aparte de servidor web, también quisiera establecer un servidor de correo webmail corporativo. Tengo un doninio de nic.ve

Es posible tener un servidor web en un puerto no-estándar por encima de 1024. Para tenerlo en los puertos estándar (80 y 443) tienes que hacer más cosas.
Lo primero, y más difícil, es lograr que te desactiven el firewall de ABA. Eso se lograba con un simple click en la página de CANTV pero hace años que no funciona dicha página, y tampoco puedes hablar por teléfono para pedirlo. Con el firewall activado, no puedes usar los puertos HTTP, HTTPS, SMTP ni SUBMIT desde el exterior, así que tus servicios estarían en puertos que no son habituales.
Supongamos que lograste desactivar el firewall ABA.
Necesitas un mecanismo para que cada vez que cambie tu IP externa de ABA, esta se registre *dinámicamente* en el servicio DNS público para tu dominio. Eso requiere cooperación del lado de tu instalación de ABA con tu proveedor de DNS: de tu lado, tienes que tener alguna aplicación que se «reporte» periódicamente con su dirección externa, y tu proveedor de DNS debe aceptar ese cambio de configuración. Hay Software Libre para lograr ambas cosas; lo más complicado es que tu proveedor de DNS ofrezca DNS dinámico para tu zona .ve.
Supongamos que lograste que cada vez que cambia tu dirección IP externa, se actualice dinámicamente en un servicio DNS que está *fuera* de ABA y prefereiblemente fuera de Venezuela.
La zona dinámica puede publicar los nombres que quieras, en particular nombres para `webmail`, y mail exchangers (MX RR). Conexiones para `webmail` van a funcionar sin mayor inconveniente siempre que la IP sea correcta. Pero el webmail no sirve de nada si no puedes enviar ni recibir correo saliente. Esto es más complicado porque en general CANTV (igual que TODOS los ISP razonables del mundo) impiden conexiones directas, entrantes y salientes, a puertos SMTP y SUBMIT desde direcciones fuera de su propia red. Eso está BIEN para que la escoria spammer lo tenga MUY difícil. La consecuencia es que cualquier tercero que quiera enviarte correo, no lo va a poder hacer directamente; y tu máquina no va a poder enviar correo directamente. Aparte, cuando la IP no esté disponible (porque ABA), el correo entrante corre riesgo de perderse. Para resolver esta situación, necesitas (1) una dirección IP que ABA no marque como «residencial» (una de las corporativas) o (2) un servicio *fuera* de ABA tal que sea anunciado como el MX permanente de tu dominio, inyecte los mensajes a tu máquina detrás de un ABA cuando esté disponible, y haga el transporte en el otro sentido también. Tiene que ser una máquina fuera de la red ABA, con direcciones fijas; se puede hacer con Software Libre, y seguramente vas a tener que ajustar el despacho para que use puertos alternativos tanto entrando como saliendo a tu máquina dentro de ABA.
ITVERX ofrece ese servicio para gente en Venezuela que quiere tener un servicio de correo decente para su dominio, con tráfico cifrado, incluso con sus servidores detrás de cualquier ISP.

View more

Hola, una pregunta, cual es la mejor forma de aprender haskell? En caso de ya haber respondido esta pregunta podria decirme si ya lo hizo, que la busque pero no la encontré. Muchas gracias

Liked by: David Prieto

Next

Language: English