472 subscribers
6 photos
1 video
2 files
550 links
python, go, code quality, security, magic

Website and RSS:
https://itgram.orsinium.dev

Source:
https://github.com/orsinium/itgram

Author:
@orsinium
https://orsinium.dev/
Download Telegram
One of the best things in Elixir is it's metaprogramming capabilities. You can write pretty performant DSLs (domain-specific languages). That means, you can naturally write on another simple language (HTML, SQL, XML, protobuf) inside of Elixir. Maybe, with a bit different syntax but the same semantics. There are some of my favorite DSLs:

+ Ecto is the best ORM I ever worked with. If you used to active record approach, you'll might feel uncomfortable at first, then you'll question why there is some repetition, but when you come through this, you'll see how ingenious are some design ideas in Ecto. Inside, it has a separate module for migrations, for schemas, for queries, for data validation, for database connection. Each module is independent and can be used on its own, but it also plays together very well. And each module has a nice and very natural DSL. For example, if you know SQL, you already can read this query:

Ecto.Query.from(p in MyApp.User, where: p.last_name == "Smith") |> MyApp.Repo.all

+ In most of the languages, when you write tests, you write functions or calsses, inside all dome magic fundtions or methods to assert something... But not in Elixir. In Elixir, you have ExUnit which is so natural way to write tests. For example:

describe "get_user_role"
test "the first user is always admin" do
assert get_user_role(1) == :admin
end
end

+ The same for HTTP endpoints. Usually, you have functions which you register later (or decorate) for expected HTTP methods and paths. In Plug, you kinda just do what you need right away:

get "/hello" do
send_resp(conn, 200, "world")
end

forward "/users", to: UsersRouter

+ Temple is a DSL for HTML. Which is, again, very natural if you know HTML (but less repetitive):

temple do
h2 do: "todos"

ul class: "list" do
for item <- @items do
li class: "item" do
div do: item
end
end
end
end

The elephant in the room is that in Temple you still have all these soup of end's at the end instead of closing tags. Python-style blocks are easier to read but in Elixir you have Ruby-style do-end. The motivation is that because of macros and all that stuff the parser needs to be able to recognize code block without knowing the context. For example, in Python, if is always a test expression and then a block to execute (which can be on the same line as any other block but it's still a block). In elixir, if is just a macro (a function) in which you pass do-end block as the second argument.

+ Re is my first Elixir library, a DSL for regular expressions:

Re.one_or_more(Re.Chars.any_digit) |> Re.compile

#elixir
Learn You Some Erlang for Great Good is the best way to learn Erlang. It's targeted at people who already know a programming language (any) and want to learn more about FP and Erlang. The author really wants to understand it all. There is a separate huge chapter on recursion and thinking recursively, with lots of detailed examples. And the whole book is in the same manner: detailed, with examples, and real-world use cases. It goes from very basic syntax to standard library, concurrency patterns and solutions, testing, distribution and so on. If you ever got interested in Erlang, definitely start there.

Now, about Erlang as a language. Why would you learn it nowadays? Well, the language itself is a bit messy, the syntax is old and alienating, static type checking is bad (and so go-to-definition will often just shrug at you), and there are not so many vacancies for it. However, underneath it is hidden a gem:

+ The best concurrency, distribution, and error handling.
+ Ability to deploy a service that will be running for 40 years without any downtime and will never interrupt a single connection,
+ Painless horizontal scaling until you have servers for it.
+ No bug will ever make everything explode and will never go unnoticed.
+ The best observability.
+ Debugging right on production without any performance degradation.

This is why Elixir appeared. Elixir is a language that provides on top of it a friendly syntax, great metaprogramming, modern package management, logging, some additional distribution primitives. But underneath it lives Erlang and all the same patterns and behaviors.

So, it's worth learning Elixir if you know the pain of distributed systems and want a tool that solves it. And it's worth learning Erlang to know better how Elixir works inside.

#erlang #elixir
Let's talk about type checking of Elixir. No-no, it's no a channel about Elixir yet but I still want to write down some of the research I do in the language.

+ Dialyzer is an Erlang type checker. It's very forgiving and so not so helpful as most of other type checkers in other languages. You can read more about it in Type Specifications and Erlang section of "Learn you some Erlang". For Elixir, it is integrated in Elixir language server and also available as dialyxir convenience wrapper.
+ Gradualizer is a new type checker for Erlang, more strict and gradual. It's still in Alpha but looks promising. For Elixir, it's available as gradient.
+ TypeCheck is an Elixir library to check types at runtime.

#elixir
The 3 Skills That Completely Change Your Social Life:

1. A good listener doesn't listen to respond. They listen to learn.
2. You don’t just listen to respond. You listen to understand. You go deeper.
3. How to never run out of things to say (I can't summarize this one in one sentence).
Maybe you should do less 'work':

1. You should try and figure out what expectations your colleagues and managers have of you. And also what you expect of yourself.
2. If you can meet these expectations in fewer hours than you are supposed to work, then you shouldn't just find more to do. Instead you should do something different.
typesplainer is a fun little tool (CLI, vscode/vim extension, and website) for explaining type annotations in a Python code in plain English. I think it has a pretty limited application (if you don't know a specific type, better read the official docs). still, might be helpful if you're starting on a project with type annotations but haven't worked with them before.

#python
Relatively recently, bloomberg open-sourced memray β€” the first memory profiler for Python that doesn't suck. I especially like their pytest plugin. I tried it and it works pretty nicely, it already found a few places in my code where memory consumption can be a bit less aggressive.

If you need to profile execution time, py-spy is still the best.

#python
awesome-bugs is a collection of articles about non-trivial bugs. It has such classic anecdotes as "Open Office Won't Print on Tuesdays" and "We Can't Send Email Farther Than 500 Miles" but also goes beyond that. Fun reading. It misses some famous ones, though, like Therac-25 scanner story, "the deadliest bug".
noclip.website is "a digital museum of video game levels". It contains levels from different games from different platforms rendered online with WebGL. Very interesting. For instance, now I know that the mirror floor in "Hotel Ocean View" from GTA Vice City is, in fact, a half-transparent floor containing a mirrored copy of the room below. Mirrors in most of videogames is a lie.
In Elixir community, there are a lot of talks about PETAL stack for dynamic websites. It stands for Phoenix, Elixir, Tailwind CSS, Alpine.js, and LiveView. The order of components doesn't make sense (except making it sound cool), so I'll cover them out of order:

+ Elixir is a functional programming language that has out-of-the-box scalability, hot reload, and other cool features that each big project needs.

+ Phoenix for elixir is like Ruby on Rails for Ruby. The default web framework. Big, powerful, and popular. Even if you write a very simple and small Elixir web app, you're likely to still use Phoenix for some of the conveniences inside.

+ LiveView is now part of Phoenix. And this is a huge game changer in web development. If you know PHP, it's similar to LiveWire. It allows you to have dynamic web pages where all content is rendered on the server side. LiveView will take care of sending data in both directions through websocket and make sure everything is stable and accounts for tons of corner-cases. At the end of the day, you will have a modern reactive website without writing a line of JS.

+ Alpine.js is for cases when you still need a bit of JS for some frontend-only logic. It's a micro framework. With LiveView, you don't really need React or anything huge like this because LiveView provides you with all nice logic, state management, components, and all that stuff. And alpine.js covers the rest. I used it for filters on my personal website and it works well. Well, it eats too much resources which is noticeable on a phone but it was easy and fun to code. So, I guess, worth it.

+ Tailwind CSS is a controversial one. It's basically CSS in your classes. When I need something low-level, I use CSS. When I need something high-level which takes care of nice defaults and adaptivity, I use bootstrap. And when I mix bootstrap with some custom CSS, I get all the same things that Tailwind CSS promises but with less boilerplate. IDK, I just don't understand yet what Tailwind tries to solve.

Someone even made petal_components Elixir library which contains Phoenix and LiveView components on top of Tailwind CSS and Alpine.js.

#elixir #web #js
verifier is a package that makes your Go code a bit nicer when you need to validate multiple things before running a block of code.

verify := verifier.New()
verify.That(transfer != nil, "transfer can't be nil")
verify.That(person != nil, "person can't be nil")
if verify.GetError() != nil {
return nil, verify.GetError()
}

They don't say it, but this is, basically, a monad. The package exists because Go doesn't have exceptions or powerful enough type system πŸ‘€ Anyway, the library is pretty helpful, remember it when you next time need to validate a lot of things.

#golang
Drunk Post: Things I've learned as a Sr Engineer. That's better than you might expect from the title.
Not IT but Gram: @laser_gram is my new small channel with photos of things I cut out of wood on my laser cutter. I also have @rpgdump with some random findings about TTRPGs and board games, and @pythonetc about Python which I hope get back to soon.
I'm surprised I haven't published it before. πŸŽ₯ Type-Driven Development in Idris is a great talk from Edwin Brady, the creator of Idris language, about, well, Idris.

Idris is a language with the best type system out there. Brady has other newer talks about Idris 2, a new more powerful version of Idris, so from the point of view of semantics this talk is a bit outdated. It was published 7 years ago! But I still think this is the best one because I want you to learn not Idris but the fundamental ideas behind it.

The Idris type system has a few very powerful features that your language, most likely, doesn't:

+ Higher-kinded types: you can write functions that operate with types as values.
+ Refined types: you can use very specific types, like "non-empty list", "even integer", "positive number", "hexadeciaml string", etc.
+ Dependent types: you can call functions from type annotations, so some types will be generated depending on types and values of other arguments. A classic example is printf function in C-like languages (or str.format in Python) where the types and amount of arguments depend on the template you pass as the first argument. For instance, if you pass "%s has %d messages", the function needs exactly 2 more arguments, and the first one must have type String and the second one must have type Integer. If you pass wrong arguments, most of the languages (I know for sure it's true for C and Go) will fail at runtime, unless you use a linter. In Idris, the error will be correctly detected at compilation time.

I watched this talk about 3 years ago when type annotations in Python were quite new thing for me and for the most of the Python community. And it changed how I think about types and static analysis in general. Showed, how cool and powerful it all might be. It inspired me to bring more static analysis into deal, including a basic formal verification.

There is my advice. Doesn't matter which language you write on, run all static analysis you can. It's almost free. Writing type annotations for everything is no-brainer, you know what type your function expects and returns anyway. And more you write annotations, cleaner they will be, because you start to think about your code in a more structured, "type-safe" manner. And good linters, even if they have false-positives, it happens not so often and usually indicates that your code is over-complicated and too magical anyway. I happened to meet multiple times engineers that were "smarter than linters", and no, they were not.

#idris
If you Google "data visualization in Python", most of the tutorials you'll see will mostly cover matplotlib. The truth is that, yes, matplotlib is very powerful and flexible tool but at the same time very low-level and hard to use. So, plenty of wrappers emerged on top of it.

The most famous wrapper is seaborn. It is very high-level and has sensible defaults to make nice looking commonly used charts with a call to a single function.

My personal favorite is plotnine, I use it all the time when I need to visualize something. It's based on the idea of "the grammar of graphics" introduced in R library ggplot2. The idea is pretty simple. In ggplot2 (and so in plotnine) the visualization consists of multiple layers: data (a data frame), aesthetics (what rows and aggregations to use for ox, oy, color, etc.), and one or more geometries (a way to visualize data using the aesthetic, like boxplot, bars, etc.). There are also "facets", "scales", and "stats", but they are also just layers.

Why this is cool:
1. It's easy to learn, explain, and understand.
2. It's easy to use and it's not so much code.
3. It's flexible, you can make any visualizations and combine them in any manner you want.

This is why the recent alpha release of seaborn (v0.12.0a1) introduced Next-generation seaborn interface. The article nods to ggplot2 and plotnine as the sources of inspiration for the new interface. But it also says the interface will be different and more "Pythonic". All that sounds very cool. Maybe, the new seaborn will win my heart over plotnine ❀️

Both libraries are one-man projects. That's crazy how much time some people can invest in a single project without getting paid. I was there but I gave up at some point on dephell when I just couldn't sleep at night for hours because of anxiety about unresolved issues... Be mindful of your health, folks.

#python
LISP in Space is a cool episode of CoRecursive podcast about automating spacecrafts with LISP, when the automation was just making its way into the field. I won't spoil too much, just listen to it.

I listened a few more episodes of the show. I also can recommend The Original Remote Developer, a story of the guy who made the first graphical text editor for Apple leaving alone in a cabin in a forest.
πŸ“šSoftware Engineering at Google is a free book from Google about engineering practices: how to lead, test, deprecate, document, measure, enforce, and review. I don't really read that kind of books, too many unnecessary words, but this one has TL;DRs. I've read all of them, and some chunks of the text that looked interesting, new, and relevant.

Some random highlights:

> there are usually a few things that everyone would like to do in the next five years: be promoted, learn something new, launch something important, and work with smart people.

> What's the best way to raise awareness about testing in a company with employees scattered around the world? After a little bit of brainstorming, someone proposed the idea of posting flyers in the restroom stalls as a joke. We quickly recognized the genius in it: the bathroom is one place that everyone must visit at least once each day, no matter what. Joke or not, the idea was cheap enough to implement that it had to be tried.

> To change the quality of engineering documentation, engineers need to accept that they are both the problem and the solution.
postgrest serves a JSON REST API on top of an existing PostgreSQL database. It provides authentication, OpenAPI schema, all operations on data, custom queries, and a lot of other cool stuff. Stop manually writing CRUDs for everything, you have other things to do.
πŸ”§ scc is a very fast and simple CLI tool for calculating lines of code in a codebase. It supports multiple languages and additionally implements an interesting stat about how many engineers, months, an money is needed to re-implement the project from ground-zero. What's interesting, I've tested it on some of our internal projects, and the result is surprisingly accurate, something like Β±5%. The big difference from most of other similar tools is the support for modern languages (like Go) and .gitignore. Oh, and performance is amazing.
πŸ”§directus is a powerful and user-friendly WebUI panel for a database. It connects to any SQL database, and provides UI for creating tables and fields, viewing and managing records, webhooks, REST API, 2FA, audit logs, versioning, roles, import and export, custom dashboards, and a lot of other stuff. The best thing you can get if you need a friendly, almost-zero-config, admin panel.

There is also nocodb but it feels more like a spreadsheet rather than an admin panel. The biggest feature they are proud of (and what makes it better for some cases than Directus) is a bunch of integrations for automating workflow. It also has some quite specific representations for data, like kanban, calendar, file view, gallery. Depending on what you need, also worth checking out.