class: middle # Rapidly building with **Gleam** --- class: middle ## **Hi** ### *name -* Peter Saxton ### *@internets -* CrowdHailer --- class: middle  [www.iindy.co](https://www.iindy.co/) --- class: middle  [gleamgathering.com](https://gleamgathering.com/) --- class: middle  [eyg.run](https://eyg.run/) --- class: middle ## The original talk - **Good advice** 1. Focus on the need 2. Seek fast feedback 3. Be boring 4. Eliminate unnecessary components --  ??? I was going to be talking about a lot that you have already heard. So what I want to do is cover some principles and then speculate on the future. Link to all the previous talks. Do 10 x developers exist? Do some projects take 10 times longer than expected --- class: middle ## The new talk - **Wild opinions** 1. *Focus on the need* 2. *Seek fast feedback* 3. *Be boring* 4. *Eliminate unnecessary components* 5. Escape the turing tarpit with your sanity 6. Bash is worse than Gleam 7. Extending types over time and space --- class: middle # Focus on need --- class: middle > Building the right thing is more important building the thing right. --- class: middle  --- class: middle > Management is doing things right; leadership is doing the right things. -- > Efficiency is doing things right; effectiveness is doing the right things. -- > There is nothing so useless as doing efficiently that which should not be done at all. -- Peter Drucker --- class: middle  --- class: middle ## Building the **right** thing - What is the problem to be solved? - Who has the problem? - When and where does the problem affect them? --- class: middle ## Building the **right** thing - What is the problem to be solved? **I'm always curious how languages work** - Who has the problem? **Me** - When and where does the problem affect them? **Whenever I discuss language features** ??? EYG was for myself and to make sure I didn't get distracted it was called language --- class: middle It's hard to start writing a blog **and** learn Rust. --- class: middle ## **Names** are important - If you can't explain something do you understand it? - If you can't name something can you explain it? - Long names are fine. - I talk to the AI "What's a better name for component in x Domain" ??? Iindy we have chats and chats and channels and channels --- class: middle ## What you **measure** matters Be very careful when: - setting up code coverage tools - tracking pull request statistics - measuring productivity in general --- class: middle > Slow is smooth smooth is fast. Not Peter Drucker --- class: middle  If you don't know what you're doing, have a coffee --- class: middle # Seek fast feedback --- class: middle ## Seek **faster** feedback - Code reload - Test quickly - Deploy quickly - Suffer real feedback --- class: middle  --- class: middle ## Types vs Tests  --- class: middle ## Default to **action** > Plans are only good intentions unless they immediately degenerate into hard work. Peter Drucker --- class: middle  [lexfridman.com/pieter-levels-transcript/](https://lexfridman.com/pieter-levels-transcript/) ??? You might not like this approach but remember what you've lost He does this all with php that brings us to our next step --- class: middle # Be boring --- class: middle ## Just use Postgres https://www.amazingcto.com/postgres-for-everything/ --- class: middle ## Convention over configuration ```rs pub fn handle(request, context) { let Request(method:, ..) = request case request.path_segments(request), method { [], http.Get -> wisp.redirect("/engine/flows") ["flows", ..rest], _ -> case rest, method { [], http.Get -> flows.index(context) ["new"], http.Get -> flows.new(context) [], http.Post -> flows.create(request, context) [id], http.Get -> flows.show(id, context) [id, "edit"], http.Get -> flows.edit(id, context) [id], http.Post -> flows.update(id, request, context) [id], http.Delete -> flows.delete(id, context) _, _ -> wisp.not_found() } _, _ -> wisp.not_found() } } ``` --- class: middle ## Docker - In local dev I run everything in docker - In production my projects use docker-compose --- class: middle ```sh FROM ghcr.io/gleam-lang/gleam:v1.12.0-erlang-alpine RUN apk update \ # git for git dependencies of the project # inotify-tools for code reloading in dev # build-base for password hashing with argon && apk add git inotify-tools build-base COPY ./ /opt WORKDIR /opt ENTRYPOINT ["gleam"] CMD ["run"] ``` ??? P.S. at iindy we use AWS and have accounts to isolate customer data an permissions Just use docker I use it for local dev, and I run docker compose in production --- class: middle ## Manage secrets **one** way Don't manage configuration at all --- class: middle *.development.env* ```sh DOMAIN=localhost OLLAMA_API_KEY=op://Development/Ollama/credential POSTGRES_PASSWORD=NotSoSecret ``` *.production.env* ```sh DOMAIN=localhost OLLAMA_API_KEY=op://Production/Ollama/credential POSTGRES_PASSWORD=op://Production/Postgres/credential ``` *$* ```sh export OP_SERVICE_ACCOUNT_TOKEN=your-service-account-token op inject -i .development.env -o .env ``` ??? env variables take choices out of our code IaC brings configuration back into our system --- class: middle ## Eliminate ~~unnecessary~~ components - eliminate boundaries - eliminate tools - eliminate concepts --- class: middle > I didn't have time to write you a short letter, so I wrote you a long one. Not Mark Twain --- class: middle ## Build a **Single** Application - web app or a browser app? - Lustre is great for browser apps --- class: middle ## Use less **tech** | Technical Requirement | Server A | Server B | | -------- | ------- | ------- | | HTTP server | Nginx | erlang | | Request processing | Ruby on Rails | erlang | | Long-running requests | Go | erlang | | Server-wide state | Redis | erlang | | Persistable Data | Redis and MongoDB | erlang | | Background jobs | Cron, Bash scripts | erlang | | Service crash recovery | Upstart | erlang | *From "Elixir in Action"* --- class: middle ## Use less **concepts** [All you need is data and functions](https://mckayla.blog/posts/all-you-need-is-data-and-functions.html) --- class: middle ## But ... > A Turing tarpit (or Turing tar-pit) is any programming language or computer interface that allows for flexibility in function but is difficult to learn and use because it offers little or no support for common tasks. --- class: middle # Escape the Turing tarpit --- class: middle # Escape the Turing tarpit* `package.json` *with your sanity --- class: middle ## High **leverage** abstractions - Garbage collection - File systems - Supervision trees - Gleam's `use` - Programming languages High leverage abstractions are elegant. --- class: middle ## Supervision trees replace - try/catch - kubernetes --- class: middle ## Gleam use ```rs // result.gleam pub fn try(result, fun) { case result { Ok(x) -> fun(x) Error(e) -> Error(e) } } ``` --- class: middle ## Gleam use ```rs fn foo() { result.try(httpc.send(req), fn(resp) { Ok(resp.body) }) } ``` ```rs fn foo() { use resp <- result.try(httpc.send(req)) Ok(resp.body) } ``` --- class: middle   --- class: middle ## Programming languages - Are for humans - A tool for organising thoughts --- class: middle ### Powerful **platforms** #### BEAM - The best platform for highly concurrent systems - Erlang/OTP is the DSL for the BEAM platform #### Browsers - The best platform for universal distribution - JavaScript/DOM is the DSL for the Browser platform --- class: middle ### Powerful **language** #### Gleam - A tool for thought. - No syntactic niceties for processes or promises. - Applicable to either platform. - Validates your assumptions with type inference. --- class: middle ## Glistix  --- class: middle ## Maximise leverage of **Gleam** --- class: middle ### Benefits of a type system  --- class: middle ### Benefits of a type system What do types add to this Python program? ```py print("Hello, World!") ``` Did you appreciate types the first day you were coding? --- class: middle What does a **type system** offer. - Consistency based on some axioms. - The axioms are the perimeter. - The wider the perimeter of our axioms the more valuable the type system. --- class: middle ### Web development  --- class: middle ### Metaframeworks, Liveview  --- class: middle ### Web development It's far more than a frontend/backend split - Local development - Build servers - CI/CD - codegen - Backend/frontend - Service workers - Background queues - Infra provisioning - Database queries How do you compose these components? --- class: middle # Bash is worse than Gleam so is `make`. --- class: middle ## The **unix** philosphy - Write programs that do one thing and do it well. - Write programs to work together. - Write programs to handle text streams, because that is a universal interface. --- class: middle ## The **unix** reality  --- class: middle ## It could be worse  --- class: middle ### Powerful **platforms** #### Linux - A great platform for running multiple applications - `.sh` is the DSL for the operating system --- class: middle ```sh wget .. \ && cd .. \ && echo .. > ``` Why not use **Gleam** --- class: middle  --- class: middle  https://github.com/CrowdHailer/gleamtours/blob/main/packages/gleamtours/src/gleamtours/dev.gleam --- class: middle  https://github.com/CrowdHailer/gleamweekly/blob/master/mailer/src/gleamweekly.gleam --- class: middle  We're stretching here. Can we do more? --- class: middle  Not with Gleam. Maybe one day. --- class: middle ## Thank you P.S.  [gleamgathering.com](https://gleamgathering.com/)