delete drafts

This commit is contained in:
Yann Esposito (Yogsototh) 2021-07-12 08:46:19 +02:00
parent b6f4e8bf32
commit c13516e0b0
Signed by untrusted user who does not match committer: yogsototh
GPG Key ID: 7B19A4C650D59646
17 changed files with 0 additions and 1919 deletions

View File

@ -1,109 +0,0 @@
#+TITLE: Are Services superior to Free Monads?
#+AUTHOR: Yann Esposito
#+EMAIL: yann@esposito.host
#+DATE: [2021-01-10 Sun]
#+KEYWORDS: haskell clojure architecture programming
#+DESCRIPTION: Here is a simple description on how to architect a big functional programming application.
#+OPTIONS: auto-id:t toc:nil
#+begin_abstract
TODO
#+end_abstract
A recurring hot topic in the functional programming world is how to make
your code scale while keeping professionnal level of code quality.
Quite often in the functional programming we communities and talk people
are focusing on enhancing specifics...
To organise your code in a functional paradigm there are many concurrent proposals.
And structuring a code application is challenging.
The way you need to structure the code generally need to reach a few
properties.
1. You should make it easy to test your code
2. You need to support modern features any modern application is expected
to provide. Typically ability to write logs, if possible send structured
logs events.
3. The code should try to help people focalise on the business logic and
put aside irrelevant technical details.
4. Split your applications into smaller (ideal composable) components
5. Control accesses between different components of your applications
The design space is quite open.
In Haskell for example, there are different proposed solutions.
One of my preferred one to start with is the Handler
Pattern[fn:handler_pattern].
Because it doesn't need any advanced Haskell knowledge to understand.
And also it prevents a classical overabstraction haskell curse I often see
within Haskellers.
No premature abstraction here.
No typeclass.
The main principle behing it is that you create /handlers/.
Handlers are /component/ focused that each provide a set of methods and
functions already initialized.
[fn:handler_pattern]: https://jaspervdj.be/posts/2018-03-08-handle-pattern.html
* Monads, MTL, RIO, Handler Pattern, Free Monad
:PROPERTIES:
:CUSTOM_ID: monads--mtl--rio--handler-pattern--free-monad
:END:
There are a lot of solutions to architecture a program while keeping all
the best properties of functional programming as well as best professional
practices.
Here too, there are different level of looking at the problem of code
organisation.
On the very high level, an application is often understood as a set of
features.
But for all of thoses features to work together it is generally a lot of
work to organise them.
So we can descend the level to look at code organisation.
Files organisation, how to group them.
Structure of the code organisation.
How to put test, etc...
If you strive for composability you generally try to understand how to
group "components" and ask yourselve what a componentn should contain.
Here is a solution.
* Free Monads/Effect System
:PROPERTIES:
:CUSTOM_ID: free-monads-effect-system
:END:
Foreword, semantic vs syntax.
The kind of best way to talk about semantic and forget about the syntax is
to deal directly with a simplified representation of the AST.
Overall API:
#+begin_src clojure
(interpret-with
[effect-1 effect-2 ... effect-n]
(let [admin-user (get-in-config [:user :admin :user-id])
admin (get-user admin-user-id)
admin-email (get admin :email)]
(log "Admin email" admin-email)
admin-email))
#+end_src
It will be up to the actual instanciation of all =effect-*= to change the
interpretation of the body.
So some effect could have different interpreation of specific symbols.
So here we can imagine that =get-in-config=, =get-user= and =log= are
handlers specified in the effects.
One advantage is that to test your code you can simply use stubbed effects.
One can use a list users
Real effects and free monads are in fact more powerful than this example
is showing.
For example, within a free monad, even =let= semantic would be changed.
But let's not take this rabbit hole in this article right now.

View File

@ -1,200 +0,0 @@
#+TITLE: Technical Opinions
#+AUTHOR: Yann Esposito
#+EMAIL: yann@esposito.host
#+DATE: [2020-11-01 Sun]
#+KEYWORDS: org-mode
#+DESCRIPTION: How I use org-mode
#+OPTIONS: auto-id:t toc:nil
#+begin_abstract
About how I forged some of my technical opinions.
How I judge some technologies.
#+end_abstract
During the early age of AI, a very promising field was Expert Systems
creation.
The goal of those systems were to put the knowledge of experts into a
computer.
As an example they tried to put the knowledge of doctors to improve and
perhaps even automate diagnosis.
And guess what?
It was a complete failure.
One advanced reason was due to doctors (and experts in general) not playing
it fair by fear of being replaced.
But I am more convinced by another explanation:
*Doctor were unable to describe correctly their knowledge.*
I believe part of their knowledge was unknown from them.
Or said otherwise; /they didn't know they knew/.
Part of that knowledge was simply an evidence to them that need no explanation.
Why?
I think it ends to internalisation.
The knowledge hardly learned through years of experience became a second
nature to those experts.
And as such, that knowledge transformed itself into an /instinct/.
The important point being that the doctors themselve didn't really have a
full consience about this knowledge.
Now what does that make us learn about programming?
If like me you are considered an expert, you have a lot of years of
knowledge.
You have internalized a lot of knowledge.
** Debates
:PROPERTIES:
:CUSTOM_ID: debates
:END:
If you read about those questions you often endup with people with strong
positive or negative opinions.
But the problem is when you read the reasons behind their opinion.
Most of these reasons are dressed as rational but under the hood,
most of them are about passions.
The typical debates:
- Editors: vim vs emacs vs ...
- OS: linux vs macOS vs windows vs ...
- imperative vs OOP vs Functional Programming
- programming languages choices
- framework choices
- language syntaxes: C-like vs S-expressions vs Python-like, etc...
- space vs tabs vs smart-mix
- colorschemes: light vs dark, high vs low contrast, yellow vs blue, etc...
And the list goes on and on.
I've read *a lot* of articles about all those subjects.
And most of the time, my opinion was mostly forged on something.
But as a geek, I tend to try a lot of new things (Editors, OS, programming
languages, frameworks, etc...)
When I look back, I think I've got quite an experience with a lot of
those choices now.
And I finally ended up with some choices that I still consider the best.
Most of time, I read a new article about "use X it's better than Y, Z, T, etc...".
As a user of X if I feel the expressed plus-values are worth it.
I generally give a try.
And I am the kind of guy that switch easily to a new tool, new programming
language, new environment if I get sufficiently plus-value.
I am what is called an /early-adopter/ in the Marketing space for most
products I use[fn:market-haskell].
Generally I'm passionate about something, and a few years after, i ever
gave up, or I switch to a new tool.
If you take a look at my [[/about.org][About me]] page you'll see the list of my current
tech environment.
So here are a few of my choices, and a short exerpt to why I use these.
I also try to mention all things I tried before.
[fn:market-haskell] Here is a pretty interresting talk by [[http://www.haskellforall.com][Gabriel Gonzales]]
about marketing for progamming languages (here for Haskell).
Because as developer we tend to ignore and even despise "Marketing".
If this is your case this is probaby worth a watch:
https://www.youtube.com/watch?v=fNpsgTIpODA
** OS
:PROPERTIES:
:CUSTOM_ID: os
:END:
I use macOS.
Why?
Mainly I consider that this is /unfortunately/ the best OS today.
I say unfortunately because I would prefer a lot that Linux would be a
better fit for me.
But I don't think this is the case yet.
Mainly why the best?
1. The hardware/OS is quite well integrated. So font quality, colors (with
a very specific gamma), integrated well working retina display.
2. Focused environment. I pass very few time tweaking the OS. I open my
computer and I can focus on my work.
3. A tremendous amount of very little design sugar everywhere makes your
life a lot easier.
4. Integration with my phone is almost flawless. Sync my passwords, my
photos, I can take call from my phone on my computer, etc...
As a developper I consider every update since Snow Leopard a bit of a
regression.
For every new feature, Apple give me a lot of anti-features.
The most annoying ones being: forced to use App Store, impossible to remove
OS Notifications, feel like an iPad/iPhone instead of like a real computer,
security to only run signed software.
I understand why they do this, but I'm a power user and I do not have
enough control of my environement as I would like.
This is why, at the second I feel I can make the switch to Linux, I will.
But I don't think this is the case.
In fact, I plan to give a try in a few days.
Probably using a VM and see what it looks like.
Previous experiences (warning I'm old):
- window (up to 98)
- Linux Debian (up to 2002)
** Programming Languages
:PROPERTIES:
:CUSTOM_ID: programming-languages
:END:
I learnt a lot of programming languages.
And really a lot more than probably necessary[fn:pl-opinion]:
- BASIC
- Logo
- Pascal
- C
- ADA
- C++
- Eiffel
- Java
- Objective-C
- PHP
- Python
- Ruby
- Awk
- Perl
- Javascript
- CamL
- Haskell
- Scheme
- Clojure
- Purescript
- Metapost
- zsh/bash/fish
- Prolog
I certainly forgot a few, I just listed the one that I either used a lot or
had an impact on me.
After a few languages it is easier and easier to learn new ones.
Mainly the concepts are always the same.
Your brain start to see the /semantic/ and slowly forget about the
/syntaxic/.
And this is probably my biggest gripe against people judging programming
languages both online and in real life.
#+BEGIN_QUOTE
PhilipWadler's Law of Language Design:
In any language design, the total time spent discussing a feature in this list is proportional to two raised to the power of its position.
0. Semantics
1. Syntax
2. Lexical syntax
3. Lexical syntax of comments
In other words, twice as much time is spent discussing syntax than semantics, twice as much time is spent discussing lexical syntax than syntax, and twice as much time is spent discussing syntax of comments than lexical syntax.
#+END_QUOTE
[fn:pl-opinion] If you are curious I [[http://yannesposito.com/Scratch/en/blog/programming-language-experience/#navigation][wrote about my biased opinion about all those languages in 2011]].

View File

@ -1,179 +0,0 @@
#+title: Create a new Haskell Project
#+subtitle: Application Tutorial
#+date: [2020-02-10 Mon]
#+author: Yann Esposito
#+EMAIL: yann@esposito.host
#+keywords: Haskell programming functional tutorial
#+DESCRIPTION: How to write Haskell application.
#+OPTIONS: auto-id:t toc:t
#+STARTUP: overview
#+begin_notes
Writing a Haskell application can be quite challenging.
You must know about:
- setup your coding environment
- get the right compiler
- use libraries
- handle your Haskell tooling, editor/IDE
- project directory structure and best practices
- write tests
- benchmarks
- profiling
- Code architecture
- encode the data structure
- manage state and effects
This is both a manual and a tutorial.
If you follow it, you should be familiar enough with Haskell to be able to
write your own applications.
I will focus on command line interfaces and REST APIs.
#+end_notes
* Haskell Environment Setup
:PROPERTIES:
:CUSTOM_ID: haskell-environment-setup
:END:
My no brainer solution for it:
1. Write this =shell.nix= file and launch =nix-shell=:
#+begin_src nix :tangle shell.nix
{ nixpkgs ? import (fetchGit {
name = "nixos-release-19.09";
url = "https://github.com/NixOS/nixpkgs";
# obtained via
# git ls-remote https://github.com/nixos/nixpkgs master
ref = "refs/heads/nixpkgs-19.09-darwin";
rev = "d5291756487d70bc336e33512a9baf9fa1788faf";
}) { config = { allowBroken = true; }; } }:
let
inherit (nixpkgs) pkgs;
inherit (pkgs) haskellPackages;
haskellDeps = ps: with ps; [
base
protolude
containers
];
hspkgs = haskellPackages;
ghc = hspkgs.ghcWithPackages haskellDeps;
nixPackages = [
ghc
pkgs.gdb
hspkgs.summoner
hspkgs.summoner-tui
haskellPackages.cabal-install
haskellPackages.ghcid
];
in
pkgs.stdenv.mkDerivation {
name = "env";
buildInputs = nixPackages;
shellHook = ''
export PS1="\n\[[hs:\033[1;32m\]\W\[\033[0m\]]> "
'';
}
#+end_src
2. now launch =summon-tui=
3. add the following nix files:
The first file to create is the one that will pin the versions of all your
packages and libraries:
#+caption: [[./my-app/nixpkgs.nix]]
#+begin_src nix :tangle my-app/nixpkgs.nix :mkdirp t
import (fetchTarball https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz) {}
#+end_src
The second file is the =default.nix= file:
#+caption: [[./my-app/default.nix]]
#+begin_src nix :tangle my-app/default.nix :mkdirp t
{ nixpkgs ? import ./nixpkgs.nix
, compiler ? "default"
, doBenchmark ? false }:
let
inherit (nixpkgs) pkgs;
name = "my-app";
haskellPackages = pkgs.haskellPackages;
variant = if doBenchmark
then pkgs.haskell.lib.doBenchmark
else pkgs.lib.id;
drv = haskellPackages.callCabal2nix name ./. {};
in
{
my_project = drv;
shell = haskellPackages.shellFor {
# generate hoogle doc
withHoogle = true;
packages = p: [drv];
# packages dependencies (by default haskellPackages)
buildInputs = with haskellPackages;
[ hlint
ghcid
cabal-install
cabal2nix
hindent
# # if you want to add some system lib like ncurses
# # you could by writing it like:
# pkgs.ncurses
];
# nice prompt for the nix-shell
shellHook = ''
export PS1="\n\[[${name}:\033[1;32m\]\W\[\033[0m\]]> "
'';
};
}
#+end_src
** Retrieve Compiler
:PROPERTIES:
:CUSTOM_ID: retrieve-compiler
:END:
** Dependency Management
:PROPERTIES:
:CUSTOM_ID: dependency-management
:END:
** Tooling
:PROPERTIES:
:CUSTOM_ID: tooling
:END:
* Haskell Project directoy structure
:PROPERTIES:
:CUSTOM_ID: haskell-project-directoy-structure
:END:
** Tests
:PROPERTIES:
:CUSTOM_ID: tests
:END:
** Benchmarks
:PROPERTIES:
:CUSTOM_ID: benchmarks
:END:
** Profiling
:PROPERTIES:
:CUSTOM_ID: profiling
:END:
* Haskell Code Architecture
:PROPERTIES:
:CUSTOM_ID: haskell-code-architecture
:END:
** Basic: IO
:PROPERTIES:
:CUSTOM_ID: basic--io
:END:
** Easy: The Handle Pattern
:PROPERTIES:
:CUSTOM_ID: easy--the-handle-pattern
:END:
** Advanced: MTL
:PROPERTIES:
:CUSTOM_ID: advanced--mtl
:END:
** Expert: Free Monad
:PROPERTIES:
:CUSTOM_ID: expert--free-monad
:END:

View File

@ -1,38 +0,0 @@
{ nixpkgs ? import (fetchGit {
name = "nixos-release-19.09";
url = "https://github.com/NixOS/nixpkgs";
# obtained via
# git ls-remote https://github.com/nixos/nixpkgs master
ref = "refs/heads/nixpkgs-19.09-darwin";
rev = "d5291756487d70bc336e33512a9baf9fa1788faf";
}) { config = { allowBroken = true; }; } }:
let
inherit (nixpkgs) pkgs;
inherit (pkgs) haskellPackages;
haskellDeps = ps: with ps; [
base
protolude
containers
];
hspkgs = haskellPackages;
ghc = hspkgs.ghcWithPackages haskellDeps;
nixPackages = [
ghc
pkgs.gdb
hspkgs.summoner
hspkgs.summoner-tui
haskellPackages.cabal-install
haskellPackages.ghcid
];
in
pkgs.stdenv.mkDerivation {
name = "env";
buildInputs = nixPackages;
shellHook = ''
export PS1="\n\[[hs:\033[1;32m\]\W\[\033[0m\]]> "
'';
}

View File

@ -1,66 +0,0 @@
#+title: Abstractions; Haskell vs Clojure
#+subtitle: How are both Haskell and Clojure good to capture some abstractions
#+date: [2020-01-18 Sat]
#+created: [2020-01-18 Sat]
#+author: Yann Esposito
#+EMAIL: yann@esposito.host
#+keywords: Haskell Clojure functional-programming
#+DESCRIPTION: Simulate some abstractions in Clojure vs Haskell
#+OPTIONS: auto-id:t toc:t
#+STARTUP: overview
#+begin_notes
This is a short essay to try to find if Haskell is as limited in its
abstractions power as I experienced many times when learning it.
Now I've got a lot more experience in Haskell and in Clojure.
I would like to see if I'll be able to manage to put some abstractions in
Haskell and in Clojure.
#+end_notes
* Abstractions
:PROPERTIES:
:CUSTOM_ID: abstractions
:END:
The notion of abstraction is generally not pretty well defined.
For example, not using pointer can be considered an abstraction.
Garbage collection is an abstraction.
Procedures are an abstraction.
ORM are an abstraction.
Monads are an abstraction.
Objects and Classes are an abstraction.
I would be surprised is not anyone has made a kind of hierarchy to organize
different abstractions as they seems to me of different nature.
In this post I will only focus on those few abstractions:
- Object Oriented Programming (Objects and Classes, inheritence, etc...)
- Frameworks for managing the lifecycle and dependencies of software
components with have runtime state (in Clojure: Component or Trapperkeeper)
- ORM/Store abstractions
* Object Oriented
:PROPERTIES:
:CUSTOM_ID: object-oriented
:END:
So in Clojure, this is quite straightforward if you consider you are
authorized to use the underlying language (java).
** Haskell
:PROPERTIES:
:CUSTOM_ID: haskell
:END:
Notion of Object, something that contain an inner state + some methods.
Notion of Class, a boilerplate for creating new Objects.
#+begin_src haskell
newtype MethodName = MethodName Text
data Object s m = Object { state :: s
, methods :: forall a. MethodName -> s -> a }
#+end_src
hmmm.... At the very begining of trying to write it down, it already suck...

View File

@ -1,39 +0,0 @@
#+TITLE: Detoxify the Web
#+SUBTITLE: Take back control of what we are exposed to on the web
#+AUTHOR: Yann Esposito
We are currently in an age were where you take your eyeball is a valuable resource.
As such there are professional, and a lot of smart ones, whose only job is to ensure
you pass more time looking at what there is best in their interrest, not yours.
There are a lot of techniques to grab your attention and not letting it go somewhere else.
- animation
- colors
- gaming the relationship
- entertaining
All of them are in fact not really problematic. But now, this is too much.
So in order to feel calm again we need to have better control of what we see, are exposed to.
If you take a look into the gopher sphere, you discover a lot text-oriented world.
Of course there are pictures, but not in the middle of the article.
So mostly text. No gif, no animation, no music, no video, just textual content.
We passed from a world where there was too much textual content, to a world filled
with meaningless animations, colors, pictures, effects, popups, etc...
*Detoxify the web*
Here is my solution:
- remove all the styles of all the websites so a lot of website cannot be used anymore that way.
- replace by a default focus oriented style.
My only solution is to start a proxy between me and the web, I take the content and do a lot of cleanup.
I remove all the CSS (faster), I use my own (nicer and contolled)
Simple and efficient.
This transformation should be done by the client.

View File

@ -1,94 +0,0 @@
#+Title:Dev problem that don't help progress
There are a lot of debates between devs. Some of them are useful because after
some time some clear winner emerge. But some are just a matter of either
personal preferences, or even worse, won't change the outcome.
Why such debate continu to live years after years is just a matter of friction.
Because my personal choices influence yours. For example, if I chose to use some
editor code style by using spaces and you prefer to use tabs. We have a problem,
and as each one of us want to keeps its habits, we might try to rationalize our
choices. While really it is just a matter of personal preference. And so, in the
end we should decide which one win.
So if you don't want to lose your time by searching to optimize your life here
are the conclusions before the debate.
* Trivial Debates
** Tools & Habits
*** vim vs emacs vs any editor
matter of personal preferences, I switched to vim keybinding mostly to prevent
hand problems, and text editing might be slighly faster at the cost of a long
training
*** font choice
**** Edit code
Simply chose a monospaced font that make a clear distinction between:
- `0` and `O`
- `1` and `l`
- ``` and `'`
- `''` and `"`
- `1` and `i`
- `8`, `B`, `6` and `0`
- `2` and `Z`
- `5` and `S`
- `|` and `!`
- `()` and `{}`
- `:`, `;` and `i`
- `.` and `,`
**** Website design
If you're not a designer don't over think about it.
Just chose one preferred Sans serif and Serif font.
*** color scheme choice
You should really use a low contrast colortheme if you want to minimize
headhache and there are good chances you'll end up preferring dark themes.
*** tabs vs spaces
Spaces appear to win slightly because the file size is not really important and
most people don't care.
Smart tabs have still some issues with alignment.
*** OS choice for working
Matter of personal preference
*** Typed (static) vs Unityped (dynamic) programming language
I've got a long answer here, but if you are a proponent to unityped programming
(dynamic typed programming) then you might not know language with great typing
system.
If you are a proponent to static typing programming then know you can live using
unityped programming.
The long answer being. Types are another abstraction. So as all abstraction, it
has some benefits and some costs. I tend to believe that once you have finished
your Proof of Concept Prototype, Types provide a lot more benefits than
drawbacks. You can think about them as free unit testing. In fact with a complex
enough type system you can think about them as an infinite number of unit tests
for free. But just know that event with advanced typing system doesn't prevent
you to write tests. But the opposite is also false, you can't simulate easily a
typing system with only tests, even generative testing.
* My Choices
** editor: spacemacs (best of vim and emacs)
** font choice: Menlo (on OS X, Hack on other OS)
** color scheme: solarized dark (each time I try to change I came back to it)
** tabs vs spaces: spaces (no configuration pb, file size doesn't matter today)
** Mac OS X: best for working, better focus, minimal configuration, setup time (would love a \*Nix env)
** configurations/dotfiles: yadm
** CVS: git with github (it's a social network)
** typed vs untyped: typed help think right, but untyped is not _that_ bad.
** Todo list, timers, note taking, thought orgnaiser: `org-mode`
* Solved but not known enough
** REST (not RESTful)
- Why REST: least surprise
** Encoding
- Use UTF-8 Everywhere <http://utf8everywhere.org>
** Readability:
- lenght of line (33em)

View File

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.github.target.lorri</string>
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
<string>-i</string>
<string>-c</string>
<string>$HOME/.nix-profile/bin/lorri daemon</string>
</array>
<key>StandardOutPath</key>
<string>/var/tmp/lorri.log</string>
<key>StandardErrorPath</key>
<string>/var/tmp/lorri.log</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>

View File

@ -1,310 +0,0 @@
#+Title: How I use nix
#+Author: Yann Esposito
#+Email: yann@esposito.host
#+Date: [2020-06-14 Sun]
#+KEYWORDS: nix programming
#+DESCRIPTION: In this article I explain how I use nix. As a brew replacement, as home environment manager, to have reproductible dev environment.
#+LANGUAGE: en
#+LANG: en
#+OPTIONS: H:5 auto-id:t toc:nil
#+STARTUP: showeverything
Have you ever written a small script and you update your system and this
stop working?
Have you copied your tool/script to another machine it doesn't work because
some dependency is missing?
Have you tried to sync your dotfiles to another env and there are a few
details not working? Some missing dependency?
If the answer is yes, then [[https://nixos.org/nix][nix]] can help.
** Scripts
:PROPERTIES:
:CUSTOM_ID: scripts
:END:
Suppose you want to write a portable script.
For example, the script I use to minify my CSS.
Here it is:
#+begin_src shell
#!/usr/bin/env nix-shell
#!nix-shell --pure
#!nix-shell -i bash
#!nix-shell -I nixpkgs="https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz"
#!nix-shell -p bash minify
minify "$1" > "$2"
#+end_src
So let's analyze each line of the header block:
- ~#!/usr/bin/env nix-shell~ :: basic, use ~nix-shell~ to run the script.
- ~#!nix-shell --pure~ :: only use dependencies installed in this nix shell
environment. A bit as if the PATH environment variable was emptied.
- ~#!nix-shell -i bash~ :: tell ~nix-shell~ to run ~bash~
- ~#!nix-shell -I nixpkgs="https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz"~ ::
pin the nixpkgs using this archive.
- ~#!nix-shell -p bash minify~ :: install ~bash~ and ~minify~ in the nix shell.
Now if the script is run on a machine with ~nix~ installed you can be
pretty sure it will work as expected.
Even if I update my OS and I forget about this script for a few years.
As long as I can install nix on the new system and I could download the tar
file the script will be run the same way as the day I wrote it.
**Remark**:
You can use any shell (like ~fish~, ~zsh~) but also other languages
~python~, ~haskell~, etc...
** Temporary working env
:PROPERTIES:
:CUSTOM_ID: temporary-working-env
:END:
Quite often, I need to do something, and run a specific command that need
me to install a very specific command.
And I'm pretty sure I will not use this tool ever again.
For those cases, what I do, is generally run my command directly with a
fresh ~nix-shell~.
#+begin_src shell
> nix-shell -p httpie
[nix-shell:~]$ ... here I can use httpie ...
#+end_src
If I don't use ~httpie~ for a while it will be garbage collected
eventually.
** Home Manager
:PROPERTIES:
:CUSTOM_ID: home-manager
:END:
A few years ago I used =brew= to install the tools I need.
With =nix= you can install a new tool with ~nix-env -i~ instead of ~brew install~.
Still recently I prefer to use [[https://github.com/rycee/home-manager][home-manager]].
The main advantage is that it is even more reproductible and can easily be
shared accross different machines.
Mainly when I need a new binary I add it in a description list in the file
=~/.config/nixpkgs/home.nix=.
It looks like this:
#+begin_src nix
home.packages = with pkgs; [
# emacs
emacsMacport
imagemagick
gnupg
# shell
direnv
...
];
#+end_src
then I simply run ~home-manager switch~ and I've got all those tools in my env.
*** Pinning the packages
:PROPERTIES:
:CUSTOM_ID: pinning-the-packages
:END:
#+begin_src nix
{ config, pkgs, ... }:
let
# ...
pkgs = import (fetchGit {
name = "nixpkgs20";
url = "https://github.com/NixOS/nixpkgs";
# obtained via
# git ls-remote https://github.com/NixOS/nixpkgs nixpkgs-20.03-darwin
ref = "refs/heads/nixpkgs-20.03-darwin";
rev = "58f884cd3d89f47672e649c6edfb2382d4afff6a";
}) {};
# ...
in {
# ...
}
#+end_src
*** Specific tools
:PROPERTIES:
:CUSTOM_ID: specific-tools
:END:
There are a few noticiable artifacts here:
The first one is ~weechat~ is a very specify build of weechat with the
plugin I need.
For that I created a new directory =weechat-with-weeslack= containing a
=default.nix=:
#+begin_src nix
{ pkgs, ...}:
pkgs.weechat.override {
configure = { availablePlugins, ... }: {
# plugins = with availablePlugins; [ python perl guile ];
scripts = with pkgs.weechatScripts; [ wee-slack ];
};
}
#+end_src
And in my =home.nix= I use:
#+begin_src nix
weechat-with-weeslack = import ./weechat-with-weeslack {
inherit pkgs;
};
#+end_src
Even if this looks cryptic.
The important detail is just that there exists a way to say to nix I'd like
to use weechat (an IRC client) with the wee-slack client (which uses python).
And nix handle the rest for me without any conflict.
*** Another nice tool is =sws=
:PROPERTIES:
:CUSTOM_ID: another-nice-tool-is--sws-
:END:
I use macOS so even though I'm using a darwin focused nixpkgs
sometimes a few package can be broken and can't be installed.
That occurred with [[https://hackage.haskell.org/package/sws][=sws=]] during the upgrade to 20.03 on darwin.
This is a simple tool that need haskell to be compiled locally and
installed.
Here is how I could install it:
#+begin_src nix
let
...
rel19 = import (fetchGit {
name = "nixpkgs19";
url = "https://github.com/NixOS/nixpkgs";
ref = "refs/heads/nixpkgs-19.09-darwin";
rev = "2f9bafaca90acd010cccd0e79e5f27aa7537957e";
}) {};
haskellDeps = ps: with ps; [
base
protolude
tidal
shake
rel19.haskellPackages.sws
];
ghc = pkgs.haskellPackages.ghcWithPackages haskellDeps;
...
in
home.packages = with pkgs; [
...
ghc
...
]
#+end_src
So I used the older version from 19.09.
** Dev environment
:PROPERTIES:
:CUSTOM_ID: dev-environment
:END:
When working on a project.
You can produce a pretty good local environment.
For example, for my blog, I only use emacs and a few shell scripts.
Still I needed to fix a few binaries, like the correct ~date~ via
~coreutils~.
And also I use ~html-xml-utils~ to easily deal with html/xml parsing.
I use it to generate my RSS xml file.
So I have a ~shell.nix~ files at the root of my project:
#+begin_src nix
{ pkgs ? import (fetchTarball https://github.com/NixOS/nixpkgs/archive/19.09.tar.gz) {} }:
let my_aspell = pkgs.aspellWithDicts(p: with p; [en fr]);
in
pkgs.mkShell {
buildInputs = [ pkgs.coreutils
pkgs.html-xml-utils
pkgs.zsh
pkgs.perl
pkgs.perlPackages.URI
pkgs.minify
pkgs.haskellPackages.sws
pkgs.cacert
];
}
#+end_src
So I just need to launch ~nix-shell~ and I have my environment.
A nice addition is to use direnv[fn:direnv] which support ~nix-shell~ by putting
~use_nix~ inside the ~.envrc~ at the root of the project.
But by default invoking ~nix-shell~ can take a few seconds everytime.
But we can do even better by using lorri[fn:lorri].
I start the lorri daemon in my ~StartupItems~ mainly I simply created
the file =~/Library/LaunchAgents/com.github.target.lorri.plist=:
#+begin_src xml :tangle com.github.target.lorri.plist :mkdirp t
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.github.target.lorri</string>
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
<string>-i</string>
<string>-c</string>
<string>$HOME/.nix-profile/bin/lorri daemon</string>
</array>
<key>StandardOutPath</key>
<string>/var/tmp/lorri.log</string>
<key>StandardErrorPath</key>
<string>/var/tmp/lorri.log</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
#+end_src
And started the daemon with:
#+begin_src bash
launchctl load ~/Library/LaunchAgents/com.github.target.lorri.plist
#+end_src
~lorri~ takes care of keeping a cache and watch my configuration change by
project.
This makes the call to ~direnv~ almost instantaneous and seemless.
I just changed the content of my ~.envrc~ with:
#+begin_src shell
eval "$(lorri direnv)"
#+end_src
And of course this would work the same way with more complex ~shell.nix~.
Typically for Haskell projects.
[fn:direnv] https://direnv.net
[fn:lorri] https://github.com/target/lorri
** Install
:PROPERTIES:
:CUSTOM_ID: install
:END:
So you would like to use nix too?
First, let's start by the bad news.
Recent macOS security policy made nix a bit harder to install on a mac.
See [[https://hydra.nixos.org/build/119559243/download/1/manual/#sect-macos-installation][macOS Installation instructions]].
Once you have nix installed you should update the nix-channel.
Mainly a nix-channels is where are the definitions of all the packages.
See [[https://hydra.nixos.org/build/119559243/download/1/manual/#sec-channels][nixOS documentation]].

View File

@ -1,91 +0,0 @@
#+TITLE: Professional Lessons and Opinions
#+AUTHOR: Yann Esposito
#+EMAIL: yann@esposito.host
#+DATE: [2019-07-04]
#+KEYWORDS: programming blog org-mode
#+DESCRIPTION: Different divagations about my experiences in the professional world of Software Developer
#+begin_comment
How to choose a programming language/paradigm to write with.
- programming is about making the program do what you want it to do.
- not much told, lot harder, and not as natural/intuitive; a program should not
do something you do not want it to do.
- programming paradigms, functional is superior because it better fit all
real-life scenarios.
- in Machine Learning, Kolmogorov complexity. Object Oriented is worse than
Functional programming to represent naturally many real life problems.
What did I learned? Is it a set of specific knowledge or can we discover great
common principles?
- restart from zero, tabula rasa, what is programming?
#+end_comment
I could talk to much about that.
But a few short written down lessons.
If you want to reach productivity and not necessarily enlightenment.
You have to stop learning and use what you know well.
And do not try to use things you don't know.
In particular, most programming languages/IDE/workflow/utils/tools have basic
and advanced features.
If your want to produce and deliver in time. Your best bet is to limit yourselves to
a minimal set of features that give you enough power of combination instead of
looking for a super generic strong solution.
Clojure for example has:
- functions
- higher-level functions
- destructuring
- defmethods
- protocols
- macros
- atoms, agents, core.async
- Java FFI
In fact, writing a fully working app you only need, basic data structure (edn) and functions.
That's it.
I was part of a team that created an advanced full featured app using only those.
No magic, just taking care of the state and not writing spaghetti code.
* How I choose
- Functional programming is superior to imperative and object oriented
languages
* Programming Languages Quality/Fun
- C, too low level, no higher level function, pb with portability
- Ruby, slow, concets not clean enough
- Python, C-like script, pretty efficient, but quite easy to write bad code, often slow
- Java, cumbersome, lot of boilerplate, not that bad, but bad underneath
philosophy (try to make programming scalable by multiple user, replace coder by gears,
in practice it is often wrong)
** Not suitable for production/ toy language
- logo
- basic
** Superior languages
Rust supersede: C, pascal, go
Clojure/Haskell supersede: Ada, C++, Eiffel, Ruby, Python
** Best choice of language depending of usage
- do something fast and dirty: zsh, perl for program shorter than 200 lines.
- very complex big software: Haskell, Clojure, Purescript, Clojurescript
- low level fast, fine grained memory control: Rust
# LocalWords: tabula rasa

View File

@ -1,68 +0,0 @@
#+Title: Programming experiences and choices
#+Author: Yann Esposito
#+Select_tags: Programming, culture
* TODO Introduction
Why each programmer tend to prefer some programming language to solve its problems.
How are we creating our preferrences?
Why one use vim and the other one can use a specialized IDE?
* Preferences depends on experiences
** Hard to understand
** Goals
* Back Story
** At first
- Logo when I was 10yo at school
- Basic when I was 11yo, with a book trying to draw lines and make games
- Basic with Amtrad CPC 6128, trying to write games from magasines
- Compiled Basic with Atari STe, write a game you are the hero in it.
- Take some courses of beginner Pascal at school, sort algorithms
** Math Background then Computer Science
- Pascal for algorithmic
- C, for basics, system and network
- C++, Eiffel for Object Oriented Programming
- A little bit of CaML (write a mathematical expression simplifier making big
usage of pattern matching)
** Ph. D. In Machine Learning
- Give courses of Logo, C, etc...
- Write lot of complex HMM related algorithms in C++ with quite complex ML algorithms
- Discover Java and its promises, play a bit with it
- Have friend that use CaML for its Ph.D. and its hash-maps are said to be
faster than C. I remember this.
** No Love for Machine Learning in 2005 :/
- Write a Java program with an User Interface in my Post Ph. D. 1/2 of the work
in the UI, the other half in the algorithm.
** Still no love for ML in 2006 Find a job just to eat
- Go find a job to eat, have a *lot* of time to learn new things
- Discover HN, /r/programming, etc...
- Web Applications are all the rage
- DCVS is still a thing, people argue between git, mercurial, bazaar, etc...
- Write a tremendous number of zsh scripts to handle a huge number of files, use Perl, etc...
** First try at startup
- Decide with a friend to make a product, choice of technology with them is _very_ hard.
- git for example was a question
- using FB connect instead of classical, name / password bullshit is refused
because they still live technically in 2000
- Design decisions are hard to make
- Programming language, I heard good things about OCaML as the fastest high
level language. Can't even talk about it.
- A guy need technicians to make its product and is willing to pay.
- OK good first thing to try ourselves.
- The other guy know Ruby, so let's go with Ruby (no rails)
- Write our own framework, many technical frictions, but in the end a PoC is
made full ruby, deployed on heroku. The product is an end-to-end personal
electrical power consumption system.
- Guy explain, I want "real time"!!!! ???? WTFBBQ!! Real time is way harder than
just drawing dashboards!!!!
- Have performance problems! Start looking into other frameworks, stumble upon
snap, an Haskell framework stating that it is _very_ fast.
- Start looking further into Haskell from there.
** Haskell learning
- Learn Haskell from web programming perspective, the goal is not to _learn_
Haskell but to _use_ Haskell to write as fast as possible a web application
with batteries included. After trying a bit, I choose to use Yesod.
- Lot of time lost due to Yesod difficulties to handle correct package version coherence!!!!
- cabal freeze, etc... to the rescue, not perfect but ok, able to deploy on heroku
- Learn Haskell in the process.

View File

@ -1,504 +0,0 @@
#+Title: Haskell Web Application from scratch
#+Author: Yann Esposito
* Introduction
** Functional Programming oriented to make a web application
** Tooling choices
- macOS Sierra
- spacemacs
- stack (not using ghc-8.0.1, there is a bug with macOS)
** High quality application
Even if an application only print "hello world" there are a lot of subtle way
such an app could fail or have problems. See for example the [changelogs to GNU
Hello](https://github.com/avar/gnu-hello/blob/master/ChangeLog).
The goal of this tutorial is not to provide a "see what we can do with Haskell"
but more, how could we enforce production quality development with Haskell.
Unfortunately, the tooling is very important in these matters.
To reach such goal we should at least provide:
- Documentation
- Unit Tests
- Generative Tests
- Benchmarks
- Profiling
- CI
- Deployment
It's easy to have one tutorial for each of these concepts, here that won't be a
deep dive, but a first introduction on how to achieve all these goals.
* Tooling and preparing to code
blog-image("stillsuit.jpg","Stillsuit")
** Warning
If you never installed Haskell before, it should be a bit long to setup a
correct working environment. So please follow me, don't give up because
something doesn't work the first time. I made my best to make my environment
work for most people.
** Installing Haskell Compiler
Install Haskell etc... In my opinion the easiest way to start is to install =stack=.
Then you need to choose a great name for your project, why not =shai-hulud=?
blog-image("shai-hulud.jpg","Shai Hulud")
#+BEGIN_SRC bash
> stack new shai-hulud tasty-travis
#+END_SRC
Yeah now you have a new directory, let use git:
#+BEGIN_SRC bash
> cd shai-hulud
> git init .
#+END_SRC
Now we have some source code, let's try it[^1].
[^1]: If you are on a Mac, please, modify the line =resolver: lts-7.18= by
=resolver: nightly-2017-01-25= to be certain to use =ghc-8.0.2= because there is
a bug with =ghc-8.0.1=.
#+BEGIN_SRC bash
> stack setup && stack build && stack exec -- shai-hulud-exe
42
#+END_SRC
** Dependencies & Libraries
As we want to make a web application let's add the needed dependencies to help
us. Typically we want a web server
[warp](https://hackage.haskell.org/package/warp) and also a Web Application
Interface [WAI](https://hackage.haskell.org/package/wai). We'll also need to use
[http-types](https://hackage.haskell.org/package/http-types).
In the =shai-hulud.cabal= file, in the =shai-hulud-exe= section, add to the
build-depends =http-types=, =wai= and =warp= like this:
#+BEGIN_SRC
executable shai-hulud-exe
default-language: Haskell2010
ghc-options: -Wall -Werror -O2 -threaded -rtsopts -with-rtsopts=-N
hs-source-dirs: src-exe
main-is: Main.hs
build-depends: base >= 4.8 && < 5
, shai-hulud
, http-types
, wai
, warp
#+END_SRC
Then we modify the =src-exe/Main.hs= file to contains:
#+BEGIN_SRC haskell
{-# LANGUAGE OverloadedStrings #-}
import Network.Wai
import Network.HTTP.Types
import Network.Wai.Handler.Warp (run)
app :: Application
app _ respond = do
putStrLn "I've done some IO here"
respond $ responseLBS status200 [("Content-Type","text/plain")] "Hello, Web!"
main :: IO ()
main = do
putStrLn "http://localhost:8080/"
run 8080 app
#+END_SRC
We'll go in detail later about what everything means.
#+BEGIN_SRC bash
> stack build && stack exec -- shai-hulud-exe
...
... Lot of building logs there
...
http://localhost:8080/
#+END_SRC
Yeah! It appears to work, now let's try it by going on <http://localhost:8080/>
in a web browser. You should see =Hello, Web!= in your browser and each time you
reload the page a new message is printed in the console because some IO were performed.
** So can we start yet?
Hmmm no sorry, not yet.
We should not use the default prelude.
While this article is a tutorial, it is not exactly a "very basic" one. I mean,
once finished the environment would be good enough for production. There will be
tests, ability to reproduce the build on a CI, and so, for such a program I
should prevent it to have runtime errors.
In fact, certainly one of the main reason to use Haskell is that it helps
prevent runtime errors.
In order to do that we'll use a prelude that doesn't contain any partial
functions. So I choosed to use =protolude=[^2].
For that that's quite easy, simply add =protolude= as a dependency to your cabal file.
We'll modify the cabal file that way:
#+BEGIN_SRC
library
default-language: Haskell2010
ghc-options: -Wall -Werror -O2
hs-source-dirs: src
exposed-modules: {-# higlight #-}Lib{-# /highlight #-}
, ShaiHulud.App
build-depends: base >= 4.8 && < 5
, http-types
, protolude
, wai
executable shai-hulud-exe
default-language: Haskell2010
ghc-options: -Wall -Werror -O2 -threaded -rtsopts -with-rtsopts=-N
hs-source-dirs: src-exe
main-is: Main.hs
build-depends: shai-hulud
, base >= 4.8 && < 5
, http-types
, protolude
, wai
, warp
#+END_SRC
We move the =app= declaration in =src/ShaiHulud/App.hs=:
#+BEGIN_SRC haskell
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
module ShaiHulud.App
( app )
where
import Protolude
import Network.Wai
import Network.HTTP.Types
app :: Application
app _ respond = do
putText "I've done some IO here"
respond $ responseLBS status200 [("Content-Type","text/plain")] "Hello, Web!"
#+END_SRC
And we remove it from =src-exe/Main.hs=:
#+BEGIN_SRC haskell
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
import Protolude
import Network.Wai.Handler.Warp (run)
import ShaiHulud.App (app)
main :: IO ()
main = do
putText "http://localhost:8080/"
run 8080 app
#+END_SRC
So now the tooling around being able to start working seems done.
** Not yet
Yes I talked about:
- Installation with =stack= that should take care of installing Haskell
- How to add dependencies by adding them to the cabal file
- Sane prelude with =protolude=
- Provided an overview of WAI Application type
But I forgot to mention part of the tooling that is generally very personal.
I use spacemacs and to take advantages of many of the editor niceties
I also use =intero= and =haddock=.
So other things to think about:
- Install =intero= with =stack install intero=.
- Also generate hoogle documentation: =stack hoogle data=
- You could also check the tests and benchmark suites: =stack test= and =stack bench=
** So we should be done with prelimiaries
So we should be done with preliminaries, at least, I hope so...
If you started from scratch it was certainly a terrible first experience. But
be assured that once done, most of the step you've taken won't be needed for your next
project.
* Web Application
So what is a web application?
** WAI
So if you look again at the code you see that your application main function
simply print =http://localhost:8080/= and then run the server on the port =8080=
using =app=.
The type of =app= is =Application=, if we look at the type of Application in
WAI, for example by using =SPC-h-h= on the Application keyword or by going in
the [WAI documentation](https://www.stackage.org/haddock/lts-7.18/wai-3.2.1.1/Network-Wai.html).
We see that:
#+BEGIN_SRC haskell
type Application = Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived
#+END_SRC
Hmmmm.... What? So just remakr WAI is at it's third major version. So if we just
take a look at WAI in its previous version we see that Application was defined
as:
#+BEGIN_SRC haskell
type Application = Request -> IO Response
#+END_SRC
Which look quite more intuitive. Because, what is the role of a web server if
not sending response to requests? The IO here is just there to explain that in
order to send a response the server might use IOs like reading in some DB or the
file system.
So why let's take a bit to analyze the new definition of =Application= in WAI 3.
#+BEGIN_SRC haskell
type Application = Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived
#+END_SRC
It is explained:
#+BEGIN_QUOTE
The WAI application.
Note that, since WAI 3.0, this type is structured in continuation passing style
to allow for proper safe resource handling. This was handled in the past via
other means (e.g., ResourceT). As a demonstration:
#+BEGIN_SRC haskell
app :: Application
app req respond = bracket_
(putStrLn "Allocating scarce resource")
(putStrLn "Cleaning up")
(respond $ responseLBS status200 [] "Hello World")
#+END_SRC
#+END_QUOTE
Great, so before it was difficult to handling some resources, now it appears to
be easier to write using =bracket_=. Hmm... =bracket_=? What is this function?
If you search it in [hoogle](https://www.haskell.org/hoogle/?hoogle=bracket_):
OK that's quite easy, you see it is a function of =Control.Exception.Base= that
we could use like this:
#+BEGIN_SRC haskell
bracket
(openFile "filename" ReadMode)
(hClose)
(\fileHandle -> do { ... })
#+END_SRC
And =bracket_= is a variation of =bracket= which doesn't need the return value
of the first computation to be used the the "closing" computation.
(More details here)[http://hackage.haskell.org/package/base-4.9.1.0/docs/Control-Exception-Base.html#v:bracket_].
So ok, an =Application= is "mostly" a function that take a =Request= an returns
an =IO Response=.
Good, now let's take another look to the =app= code:
#+BEGIN_SRC haskell
app :: Application
app _ respond = do
putText "I've done some IO here"
respond $ responseLBS status200 [("Content-Type","text/plain")] "Hello, Web!"
#+END_SRC
As you see we don't use the first parameter, the =Request=. So we could ask for
some JSON data on =/foo/bar/= with a POST, it will still respond an HTTP 200
with content-type plain text containing the body =Hello, Web!=.
So what a web app should provide. And here we could go down the rabbit hole of
the HTTP standard and all its subtleties. But the first thing to come in mind is
"how to handle routing"?
One of the advantage of using a language with some types flexibility is to use
the types as a high level specification.
** Routing
#+BEGIN_SRC haskell
data ShaiHuludApp = Routes -> Application
#+END_SRC
That's easy, provided a "Routes" representation we should be able to "generate"
a WAI Application. Now how should we represent a set of =Routes=?
We should split them by:
- HTTP Verb: =GET=, =POST=, =PUT=, =DELETE=, =HEAD=, =OPTIONS=, ...
- Path: =/=, =/users/:userID= ...
- Content-Type: =application/json=, =text/plain=, =text/html=, =text/css=,
=application/javascript=...
Hmmm....
So it is immediately very difficult. And these are just the basic requirement,
what about all subtelties about Standardized Headers (CORS, ETags, ...), Custom
Headers...
** Is that FP compatible?
As a functional programmer, and more generally as a scientis, math lover I
immediately dislike that profusion of details with a lot of ambiguities.
For example, REST is still ambiguous, should you use POST / PUT to update?
Should you put a parameter in:
- part of the path like =/user/foo=
- in the query param of the URI =/user?userID=foo=
- in the body? Then what parser should we use? FORM param, JSON, XML?
- in the headers?
- Why not as an anchor? =/user#foo
- How should I provide a parameter that is a list? A set? A Hash-map? Something more complex?
The problem of web programming come from the tooling. Browsers and HTTP evolved
together and some feature existed in browser before people had really the time
to think corectly about them.
That's called real-life-production-world. And it sucks! For a better critique of
web standards you should really read [the chapter «A Long digression into how
standards are made» in Dive into
HTML5](http://diveintohtml5.info/past.html#history-of-the-img-element).
So how could we get back our laws, our composability? Our maths and proofs?
We have a lot of choices, but unfortunately, all the tooling evolved around the
existing standards. So for example, using GET will be cached correctly while
POST won't. And a lot of these details.
*** FP Compatible Web Programming?
Let's re-invent web programming with all we know today.
First, one recent trends has changed a lot of things.
Now a web application is splitted between a frontend and backend development.
The frontend development is about writing a complete application in a browser.
Not just a webpage. The difference between the two notions is blurred.
Once consequence is that now, backend application should only present Web API
and should never send rendering informations. Only datas. So this is a
simplification, the backend should simply expose "procedures", the only things
to think about are the size of the parameter to send and the size of the
response. As every of these objects will go through the wire.
But there are interresting rules:
- =GET= for read only functions
- =POST= generic read/write functions
- =PUT= idempotent read/write functions
- =DELETE= like =PUT= but can delete things
But there are also HTTP code with so many different semantics.
- =1xx=: technical detail
- =2xx=: Successful
- =3xx=: Redirection
- =4xx=: Client Error
- =5xx=: Server Error
So there are some similarities with the HTTP 1.1 reference and the control on
functions we try to achieve with Haskell.
One thing I'd like to imagine is simply that a Web API should simply be like a
library. We could simplify everything _a lot_ by removig most accidental
complexity.
If we consider a web application to be split between a frontend application and
a backend application it changes a lot of things. For example, we could mostly
get rid of urls, we can consider to use the backend as a way to expose
procedures.
Let's for example decide to use only POST, and send parameters only in the body.
In Haskell we could write:
#+BEGIN_SRC haskell
foo :: IO X -- ⇒ POST on /foo
bar :: A -> IO X -- ⇒ POST on /foo with a body containing an A
#+END_SRC
And that's it.
* Appendix
** Haskell Fragmentation vs Di
There are many other prelude, one of my personal problem with Haskell is fragmentation.
Someone could see "diversity" another one "fragmentation".
Diversity is perceived as positive while fragmentation isn't.
So is diversity imply necessarily fragmentation?
Could we cure fragmentation by making it hard for people to compete?
I don't think so. I believe we could have the best of both world.
Then fragmentation occurs. And fragmentation is bad, because if you have an
issue with your choice, the number of people that could help you is by nature
reduced.
I would say that there is fragmentation when there is no one obvious choice. But
having an obvious choice for a library for example doesn't really prevent
diversity. Fragmentation:
- NixOS, raw cabal + Linux, stack
- preludes
- editor
- stream library
- orientation of the language "entreprisy ready, production oriented" make
it work being dirty, add dirty choices for research people working in the
language, "research oriented" make it beautiful or don't make it, block
entreprisy people.
** =bracket_=
[^3]: Also if you are
curious and look at its implementation it's quite short and at least for me,
easy to inuit.
#+BEGIN_SRC haskell
bracket :: IO a -- ^ computation to run first (\"acquire resource\")
-> (a -> IO b) -- ^ computation to run last (\"release resource\")
-> (a -> IO c) -- ^ computation to run in-between
-> IO c -- returns the value from the in-between computation
bracket before after thing =
mask $ \restore -> do
a <- before
r <- restore (thing a) `onException` after a
_ <- after a
return r
bracket_ :: IO a -> IO b -> IO c -> IO c
bracket_ before after thing = bracket before (const after) (const thing)
#+END_SRC
Very nice

View File

@ -1,104 +0,0 @@
#+TITLE: Regression
#+AUTHOR: Yann Esposito
Depuis quelques années on peut constater un mouvement que l'on pourrait
qualifier d'anti-progressiste.
Certain signes sont de plus en plus visible.
Le mot /progres/ est peu a peu remplacé par le mot /innovation/.
On voit dans la literature que ce qui se cache derriere ce vocabulaire
est en realité un état qui donne l'impression de progres, mais qui se fait
remplacer par du mouvement immobile. Une sorte d'effet sysiphe.
Alors que tout semble s'accélerer dans le monde, en réalité un observateur
attentif constatera que les etapes de progres ralentissent, ou meme que l'on
assiste a des regressions dans beaucoup de domaines.
- politique: retour a des valeurs anciennes
- ecologie: c'est comme si rien n'avançait dans ce domaine,
on continue la course vers la catastrophe. Pire les personnes militantes
veulent un retour à l'ancienne, et ont une approche technophobe.
On peut même entendre des discours proches de ceux de Unabomber.
- societé: les réseaux sociaux ont eu un effet inattendu, au lieu d'avoir plus
d'échange entre les groupes, des communautés isolées se sont naturellement
créées. L'effet sur la vie en société est dramatique, les gens ne se
comprennent plus, l'effet Internet/reseau social rend les plus virulents
les plus visibles laissant les réflexions de fond dans l'ombre. Donnant
l'impression a chaque personne dans chaque sous-communauté que les autres
communautés ne sont composé que de militants complètement lavés du cerveau.
Les échanges courtois ne sont pas assez suivis. La controverse est ce qui
permet de faire tourner les pompes des réseaux sociaux et donc de monetiser
les plateformes qui hebergent ces données.
- informatique: de la meme façon que le reste de la société, les débats
informatiques se sont radicalisés. Ceux qui préferent X et ceux qui préferent
Y trouvent un moyen de se ridiculiser à coups d'insultes radicalisant encore
plus chaque parti. Le pire de tous ces débats, c'est que souvent la discussion
se passent au mauvais endroit. C'est l'équivalent de tracer une ligne quelque
part sur le sol d'un pays étranger et de décréter que c'est la nouvelle ligne
entre deux nouveaux états sans prendre le temps d'analyser si cette ligne
est réelle ou non. Quelques exemples de faux debats ou de debats mal placés:
- languages dynamiquement typés vs languages statiquement typés
- languages imperatifs vs languages objets vs languages fonctionnels
- choix de l'éditeur
- choix de l'outil de communications (mail, chat, gestion de projet, etc...)
- choix du process de l'organisation du travail
- les drama sur les outils sont classiques
- les drama sur le process de creation d'un projet open source, etc...
Pour tous ces débats incessants il suffit de passer assez de temps a réfléchir
sur le fond pour s'apercevoir que le debat est mal placé. Le pb réel étant
souvent bien plus complexe. Mais il est plus facile de s'insulter en étant
certain que ses préférences personnelles sont de façon évidentes encrées dans
des choix objectifs basés sur l'expérience. En celà tout ceux qui pensent
différemment doivent être exterminés/disparaître et pour y arriver osons les
arguments qui ridiculisent et/ou insultent. Il suffit d'analyser ces
conversations pour s'apercevoir qu'il s'agit généralement d'une minorité qui
arrive à ces extremités, mais qui pourri l'ambiance générale et force les gens
à prendre parti pour les personnes et oublier le fond.
Il est normal et sains que ce type de débats existent. Mais la limite s'arrête
avec les mouvements de masse. Aujourd'hui, nous sommes sous bloqués par la peur
de dire ce que nous pensons publiquement. Tous les arguments sont mal compris
par une minorité militante et qui n'hésitent pas à faire du bashing contre le
malheureux qui démontre un coté qu'ils voudraient voir disparaitre.
* Causes
The single one major cause of most of those regression is certainly
capitalism effect with the fact that the system became aware that
brain/eyeball time is valuable.
From now own, a lot of professional system extremely agressive do
their best to grab your attention.
And unfortunately for us humans, our brain can be hacked and exploited.
This is why we are in a world of system that do their best to
disrupt your recompense system.
I think this is a major mondial health issue. Now people have become aware
of the problem, but the effect as already affected us.
The IQ is going down, our capability to focus on something a bit slow
is almost null right now. Try to read an old book for example.
And you'll have a hard time being able to fight agains yourself.
Because you want immediate action that will provide you immediate positive
feedback.
The world is McDonalidised. What McDonald did to the food, is going to be done
on most other things.
*note*: psychological (individual) vs social story telling
* Reaction
How can we fight back? Should we? Or should we embrace the change and try to use
that knowledge to reach the next step.
This is what I'm thinking about more and more.
We as a species destroy everything behind us.
And I don't want to judge and say, it would be better if we were different.
I kind of have that nostalgic feeling time to time. It almost feel reachable.
Still, even if many books have a huge influence on the world. The current system
is done that only a few bad player can piss in the swimmingpool for everybody.
So I think it is time to think about a new utopia, but this time that will take
into account modern research about humanities and how we can make it everyhting
for the best.

View File

@ -1,62 +0,0 @@
#+Title: On Scrumm
It is of good taste these day to critique Scrumm.
Here are my 2cents
* Personal Experience with Scrum:
** Discovering
- Fear and counter arguments
** Efficiency
- Time lost in meeting
** People tensions
- instead of tamming it made everything worse.
* Management: The root of all evil?
The root of the problem is between the developpers and the managers.
- Manager: I want a great product, I want to finish it fast, I want my customers to love it
- Developer: I want a great product, I want to finish it fast, I want customers to love it
What could go wrong?
- What Manager means: _I want a great product_:
I want to sell it!
- What Developer means: _I want a great product_:
I want it to use the last technology, with the last code organization/quality trends
- Manager: _I want to finish it fast_:
I don't want to listen to technical discussion,
this looks like something easy to do.
It should be in my hand in few weeks.
- Developer: _I want to finish it fast_:
I want to keep the code clean to be able to add new changes fast
with confidence (without breaking anything)
this certainly means, testing + testing environment + proofs ...
- Manager: _I want customer to love it_:
They should buy more and more. The product should be useful.
- Developer: _I want customer to love it_:
User should enjoy using it. The product should be simple, clean, natural, beautiful.
The two meaning are'nt completely opposite.
Still they are quite different.
* What could we do about it?
How to solve the problem?
- Spoiler: _you can't_.
The root of all evil is "it looks easy, do it".
Proof, a guy made the same thing in PHP in 2003, or I saw the same shit in Flash around 1998.
You have two choices:
1. Use tools to finish your work fast, but the cost is very to maintain and modify.
2. Use tools that enforce quality, you'll have a starting cost.
Error not to do:
- Manager ask for something, you use your l337 H4X0R cape and you show him
something in less than 10 minutes.
- Manager believe that everything should be as fast
- Discover what you did was just a terrible hack, and take 2 days to finish it
correctly.
- Manager doesn't really understand why he _saw_ it right now, and has to wait
many days to really have it in production.

View File

@ -1,16 +0,0 @@
#+title: Return of experience about colorscheme
#+date: [2020-05-04 Mon]
#+author: Yann Esposito
#+EMAIL: yann@esposito.host
#+KEYWORDS: colorscheme
#+DESCRIPTION: The list of colorschemes I used, why I changed.
#+OPTIONS: auto-id:t toc:nil
#+STARTUP: overview
* Local variables :noexport:
:PROPERTIES:
:CUSTOM_ID: local-variables
:END:
# local variables:
# org-download-image-dir "./img"
# end:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

View File

@ -1,16 +0,0 @@
#+TITLE: The sad state of text browsing
#+AUTHOR: Yann Esposito
1. sad state, show HN, Reddit, worse, news websites, etc...
2. bad for disabled people
3. why not change the concept and make the provider of content not also
provide the Look & Feel.
User controlled display of content.
Less money, more quality, is it possible
- no js
- text only
- interaction? controlled one
- user facing code, yes, only signature, all the rest looks like bullshit to me
4. not web 3.0, more like, fuck it, we need a BRUTALIST, Hacker-only
oriented web. A safe place to talk between civilised people. What are
the possible solutions