Clear explanation of Rust’s module system

This blog post helped me clear my understanding of how Rust’s module system works. This is required reading to all beginners.

Rust’s module system is surprisingly confusing and causes a lot of frustration for beginners.

In this post, I’ll explain the module system using practical examples so you get a clear understanding of how it works and can immediately start applying this in your projects.

Since Rust’s module system is quite unique, I request the reader to read this post with an open mind and resist comparing it with how modules work in other languages.

Sheshbabu Chinnakonda

Link to post

Published
Categorized as Default

El Lenguaje de Programación Perfecto

En mi trabajo escribo principalmente TypeScript sobre Node.js y aunque no es mi lenguaje favorito, no me molesta, tiene muchas cosas buenas. Para el tipo de proyecto que trabajo, el tener un “type system” es altamente valioso.

También escribo bastante Python (de mis lenguajes favoritos) para “scripts” locales y otras cosas que no necesariamente terminan en un ambiente de producción. Algún día escribiré un poco más sobre porque terminamos corriendo en Node.js y MongoDB.

No creo que exista el lenguaje de programación perfecto, perdón por el “clickbait”, pero para mi el lenguaje ideal es una mezcla entre Python, TypeScript, Go y Rust.

En este post enumero los ingredientes que me gustaría tomar prestados para un lenguaje nuevo imaginario. Seguramente este lenguaje jamás existirá y posiblemente eso sea lo mejor. Si hay algo que NO soy, es diseñador de lenguajes de programación.

Python

De Python me encanta que es fácil de leer y escribir y que tiene un “standard library” bastante completo. Cuando quiero resolver un problema que se puede resolver corriendo un pequeño “script” local, Python siempre me da los mejores resultados. Además hay muchas librerías para manejar datos y visualizaciones que son fáciles y útiles.

En cuanto “web apps” que es lo mas que hago, creo que Django es de lo mejor que he usado. Todo lo importante está incluido y lo que falta es fácil de añadir. Me gustaría que fuera un poco más flexible en cuanto a como organizar los proyectos para hacer mas fácil implementar una arquitectura hexagonal pero al final del día no tengo quejas mayores.

  • Fácil de leer y escribir.
  • El “standard library” es bastante completo.
  • Hay muchas librerías para análisis y visualización de datos.
  • Me encanta Jupyter Notebook.
  • Django es mi web framework favorito.

TypeScript y JavaScript

De TypeScript me gusta mucho el “type system” y principalmente la idea de que puedes añadir los tipos poco a poco en un “codebase” viejo. Se que Python tiene su propio “type system” pero de lo que he visto el de TypeScript es mas poderoso y no es mucho más difícil de aprender.

Otro feature de TypeScript y JavaScript que me gusta mucho es la sintaxis para los “arrow functions(args) => body. Además de facilitar el crear funciones anónimas creo que hace que el código sea más fácil de leer, especialmente cuando se usa map y filter.

Python tiene los list y dictionary comprehensions que me gustan bastante, pero creo que la sintaxis de los “arrow functions” es un poco mejor. Tambien en Python hay lambdas para definir funciones anónimas pero nunca recuerdo como se escriben. Sin duda los “arrow functions” son mejor.

  • El “type system” es buenísimo y opcional.
  • Me parece que el “type system” es mas poderoso que lo que ofrece Python en versiones mas recientes.
  • Es fácil de aprender a sacarle provecho a los “types”.
  • Los “arrow functions” en JavaScript me gustan más que los list y dictionary comprehensions de Python.
  • Hacer funciones anónimas es mucho más natural que en Python.

Go

De Go lo más que me gusta es el modelo de concurrencia. Los goroutines hacen que sea fácil escribir código concurrente sin errores, algo que es un poco más complicado en Node y ni hablar de Python.

Otra cosa que me parece buenísima es la posibilidad de generar binarios “statically linked” para Windows, Linux y Mac. Un solo archivo binario con todas sus dependencias hace posible crear contenedores de Docker pequeños usando FROM scratch.

El tema de “performance” aunque no es una de las cosas que más me emocionan de un lenguaje, no se debe ignorar. Go al ser un lenguaje compilado produce programas que ejecutan mucho más rápido que programas escritos para Node o Python. Sin duda esto es algo positivo especialmente cuando estás haciendo “hosting” en la nube.

  • El modelo de concurrencia facilita escribir código concurrente con menos errores.
  • Compilar a un solo binario “statically linked” facilita “deploys” y el manejo de dependencias.
  • Poder hacer un contenedor FROM scratch permite tener imágenes pequeñas y con la menor superficie de ataque posible.
  • Mejor “performance” cuando se compara con Python o Node.

Rust

De Rust me gustan muchas cosas pero el enfoque del lenguaje en producir programas que sean fácil de analizar estáticamente, ha empujado ese lenguaje a tomar decisiones conservadoras sobre como manejar los datos.

El que todo sea inmutable por “default” sin duda es bueno para facilitar el análisis estático del programa y ayuda al programador a no tener sorpresas.

Los tipos Option y Result son otra cosa que me encanta de Rust. Estos dos tipos se encargan de manejar errores y funciones que pueden no devolver el valor que esperas. Esto te obliga a ser extremadamente explicito manejando errores y los casos donde el programa puede fallar. Nuevamente esto ayuda al programador a no tener sorpresas.

  • Toda la data es inmutable por “default”.
  • Al igual que Go los errores son valores que hay que atender de forma explícita.
  • Los tipos Option y Result son enormemente útiles y me gustan mas que el if err != nil {} que se ve en todas partes en Go.
  • Los “features” de “pattern matching” en combinación con Option y Result son una maravilla.

Conclusión

Ahí está, mi lenguaje de programación ideal es una mezcla de algunas ideas y “features” de estos cuatro lenguajes. ¿Te gustaría un lenguaje así?

Photo by Raimond Klavins

Published
Categorized as Default

Web History

Recientemente escuché esta serie de podcasts sobre la historia de la web y me encantaron. Creo que cualquiera que trabaje construyendo la web debería conocer un poco sobre su historia y esta serie me parece ideal para eso.

Muy recomendado.

https://css-tricks.com/category/history/

Published
Categorized as Default

You Don’t Need NPM Scripts

If you have done any Node.js development, you’ve likely used NPM, and you should know that on your package.json file, you can add simple scripts that can be executed using npm run <name of script>. At first, this might seem convenient, and since most projects use it, why not use it.

In my experience, NPM scripts have a few problems.

  • They are encoded as JSON strings that don’t have syntax highlighting or linting by default on most editors.
  • Strings in JSON must be double-quoted, which produces the need to escape double quotes inside your scripts.
  • Longer scripts make your package.json difficult to read and understand.
  • On larger projects, you might need many scripts which can become unmanageable quickly. 
  • Scripts are all on a single namespace forcing you to invent naming conventions like build:css, build:js, build:production:js, etc.

The only good reason to use NPM scripts is to hook into life cycle events like postinstall, prestart, and friends. If you need something more than mocha src/**/*.test.js, you will be better off avoiding NPM scripts.

My suggestion is to create a top-level folder named scripts and organize it however you like. Inside the scripts folder, you will have executable files without file extensions, and each file must begin with the correct shebang line. 

Here’s an example from one of my projects. This file is located at scripts/build, which can be invoked by running ./scripts/build on the root of the project.

#!/usr/bin/env bash
#
# Build project for production
#
set -euf -o pipefail

echo "-> Building App..."

# Remove old files if they exist
rm -rf ./build

# Run postcss build
./scripts/css-build

# Copy images to build
./scripts/img-build

# Run server TypeScript build
echo "-> Compiling server-side TypeScript..."
npx tsc

# Run client side JS build and minify
./scripts/js-build

# Copy other files to build dir
echo "-> Copiying *.hbs and *.json files..."
npx copyfiles --up 1 ./src/**/*.{hbs,json} ./build

echo "-> Build done"

This example is written in bash because it is a very short list of commands, each calling another smaller and much more focused script. You don’t have to use bash. Actually, if your script is more than a few lines long and requires some sort of logic, you might be better off using a more familiar programming language like JavaScript or Python or whatever you like.

Here’s the smallest possible example using Node.js as the runtime. This script can be invoked with ./scripts/node-env.

#!/usr/bin/env node
/**
 * Print the current NODE_ENV
 */
console.log(`NODE_ENV='${process.env.NODE_ENV}'`);

That’s it, that’s the idea. Just to recap:

  • Create a top-level scripts folder and add your scripts to it.
  • Scripts must not use a file extension. This will make it easier to change the language later.
  • Add the required shebang like to the file. 
  • Make sure the scripts are executable by running chmod +x scripts/<name of script>.
  • Invoke scripts by running ./scripts/name.
  • Only use NPM scripts to hook into the life cycle events like preinstall, postinstall, etc.
  • If you use one of the life cycle event hooks, just call one of your scripts.

Let me know what you think.

Photo: Unsplash

Published
Categorized as Default

Paste JSON as Code

This is a quick post to recommend the Visual Studio Code extension Paste JSON as Code. The extension does exactly what it says on the name. You copy a piece of JSON, select paste as code, and the extension will generate and paste an interface for that JSON structure. It is super helpful when writing TypeScript.

Give it a try if you are using a statically typed language. It has support for a lot of them.

Published
Categorized as Default

Your career needs a vision

Link: https://swizec.com/blog/your-career-needs-a-vision

It is well known the drunken sailor who staggers to the left or right with n independent random steps will, on the average, end up about √n, steps from the origin. But if there is a pretty girl in one direction, then his steps will tend to go in that direction and he will go a distance proportional to n. In a lifetime of many, many independent choices, small and large, a career with a vision will get you a distance proportional to n, while no vision will get you only the distance √n, . In a sense, the main difference between those who go far and those who do not is some people have a vision and the others do not and therefore can only react to the current events as they happen. 

The Art of Science and Engineering, Richard Hamming

Published
Categorized as Default

Bad names make you open the box

From the blog post “Bad names make you open the box” by Adam Zerner.

Imagine that you open the fridge. You see something labeled “brownie”. You eat it.

Then you hop in the car and start heading over to your friends house. But right as you merge on to the highway, you start feeling funny.

Turns out that the “brownie” label was a little misleading. It wasn’t a regular brownie. It was a pot brownie. There was something dangerous inside the brownie, but the label didn’t reflect that.

This is similar to poorly named functions with dangerous side effects. In both cases, if the thing in question can have dangerous side effects, you really want to make sure that it is reflected in the label. You can’t trust that people will read beyond the label. And even if you could, you wouldn’t want people to have to do that. You’d rather them be able to get the information they need from the label.

Adam Zerner
Published
Categorized as Default