Save in progress
This commit is contained in:
parent
1b82f80cb4
commit
0755dd4d04
7 changed files with 853 additions and 5 deletions
94
src/drafts/blog-false-programmer-problems.org
Normal file
94
src/drafts/blog-false-programmer-problems.org
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
#+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)
|
62
src/drafts/blog-on-SCRUM.org
Normal file
62
src/drafts/blog-on-SCRUM.org
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#+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.
|
69
src/drafts/blog-programming-choices.org
Normal file
69
src/drafts/blog-programming-choices.org
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
#+Title: Programming experiences and choices
|
||||||
|
#+Author: Yann Esposito
|
||||||
|
#+Language: English
|
||||||
|
#+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.
|
504
src/drafts/blog-raw-haskell-web-app.org
Normal file
504
src/drafts/blog-raw-haskell-web-app.org
Normal file
|
@ -0,0 +1,504 @@
|
||||||
|
#+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
|
104
src/drafts/blog-regression.org
Normal file
104
src/drafts/blog-regression.org
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
#+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.
|
|
@ -95,15 +95,25 @@ I write all the content with [[http://orgmode.org][org-mode]].
|
||||||
(when (and i (stringp i))
|
(when (and i (stringp i))
|
||||||
i)))
|
i)))
|
||||||
|
|
||||||
|
(defun rand-obfs (c)
|
||||||
|
(let ((r (% (random) 20)))
|
||||||
|
(cond ((eq 0 r) (format "%c" c))
|
||||||
|
((< 0 r 10) (format "&#%d;" c))
|
||||||
|
(t (format "&#x%X;" c)))))
|
||||||
|
(defun obfuscate-html (txt)
|
||||||
|
(apply 'concat
|
||||||
|
(mapcar 'rand-obfs txt)))
|
||||||
|
|
||||||
(defun org-blog-postamble (info)
|
(defun org-blog-postamble (info)
|
||||||
"Post-amble for whole blog."
|
"Post-amble for whole blog."
|
||||||
(concat
|
(concat
|
||||||
"<div class=\"content\">"
|
"<div class=\"content\">"
|
||||||
"<footer>"
|
"<footer>"
|
||||||
"<hr/>"
|
|
||||||
(when-let ((author (get-from-info info :author)))
|
(when-let ((author (get-from-info info :author)))
|
||||||
(if-let ((email (plist-get info :email)))
|
(if-let ((email (plist-get info :email)))
|
||||||
(format "<div class=\"author\">Author: <a href=\"mailto:%s\">%s</a></div>" email author)
|
(format "<div class=\"author\">Author: <a href=\"mailto:%s\">%s</a></div>"
|
||||||
|
(obfuscate-html email)
|
||||||
|
(obfuscate-html author))
|
||||||
(format "<div class=\"author\">Author: %s</div>" author)))
|
(format "<div class=\"author\">Author: %s</div>" author)))
|
||||||
(when-let ((date (get-from-info info :date)))
|
(when-let ((date (get-from-info info :date)))
|
||||||
(format "<div class=\"date\">Created: %s (%s)</div>" date (y-date date)))
|
(format "<div class=\"date\">Created: %s (%s)</div>" date (y-date date)))
|
||||||
|
@ -117,7 +127,6 @@ I write all the content with [[http://orgmode.org][org-mode]].
|
||||||
"<a href=\"http://orgmode.org\" target=\"_blank\" rel=\"noopener noreferrer\">Org Mode %s</a>"
|
"<a href=\"http://orgmode.org\" target=\"_blank\" rel=\"noopener noreferrer\">Org Mode %s</a>"
|
||||||
"</div>")
|
"</div>")
|
||||||
emacs-version spacemacs-version org-version)
|
emacs-version spacemacs-version org-version)
|
||||||
"<hr/>"
|
|
||||||
"</footer>"
|
"</footer>"
|
||||||
(menu)
|
(menu)
|
||||||
"</div>"))
|
"</div>"))
|
||||||
|
@ -219,3 +228,10 @@ I write all the content with [[http://orgmode.org][org-mode]].
|
||||||
(add-to-list 'org-export-filter-link-functions
|
(add-to-list 'org-export-filter-link-functions
|
||||||
'my-org-export-add-target-blank-to-http-links)
|
'my-org-export-add-target-blank-to-http-links)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src elisp :results verbatim
|
||||||
|
(obfuscate-html "yann.esposito@gmail.com")
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: "yann.esposito@gmail.com"
|
||||||
|
|
|
@ -12,7 +12,7 @@ I used include and took care of XHTML pages validation.
|
||||||
Then I used [[http://nanoc.ws][nanoc]], a ruby static website generator.
|
Then I used [[http://nanoc.ws][nanoc]], a ruby static website generator.
|
||||||
Then I switched to [[https://jaspervdj.be/hakyll/][hakyll]] because I wanted to switch to a Haskell's written
|
Then I switched to [[https://jaspervdj.be/hakyll/][hakyll]] because I wanted to switch to a Haskell's written
|
||||||
tool.
|
tool.
|
||||||
Now I'll try to use [[http://orgmode.org][org-mode]].
|
Now I'll try to use [[http://orgmode.org][org-mode]] directly with [[https://orgmode.org/worg/org-tutorials/org-publish-html-tutorial.html][org-publish]].
|
||||||
|
|
||||||
* Why?
|
* Why?
|
||||||
|
|
||||||
|
@ -45,5 +45,4 @@ org-mode files.
|
||||||
One real game changer is ~org-capture~.
|
One real game changer is ~org-capture~.
|
||||||
You can add a task quite easily while doing other work in emacs.
|
You can add a task quite easily while doing other work in emacs.
|
||||||
|
|
||||||
|
|
||||||
[fn:vim] I wrote this article to help people use vim: [[http://yannesposito.com/Scratch/en/blog/Learn-Vim-Progressively/][learn vim progressively]]
|
[fn:vim] I wrote this article to help people use vim: [[http://yannesposito.com/Scratch/en/blog/Learn-Vim-Progressively/][learn vim progressively]]
|
||||||
|
|
Loading…
Reference in a new issue