465 karma · joined January 29, 2022
> Unfortunately, one of the challenges of running Docker on macOS or Windows is that these Linux primitives are unavailable. Docker Desktop goes to great lengths to emulate them without modifying the user experience of running containers. It runs a (light) Linux VM to host the Docker daemon with additional "glue" helpers to connect the Docker client, running on the host, to that VM.
https://mirage.io/blog/2022-04-06.vpnkit
WASM and WASI would actually be a cross compatibility story because you could compile to an architecture and syscall interface that is platform agnostic.
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
I think that Erlang/Elixir could make amazing TUI apps if they were easier to distribute. The ability to push work to the edges of the system while keeping the UI responsive would be awesome. It sounds like static binaries provided by Firefly would make this a viable option.
Do I think it will happen? Not quite.
append34 := func() func([]int) []int {
If I was going to rank the readability I would say:1. Rust function bodies 2. Go code 3. Rust function signatures 4. C++ code
Which you could argue is me shifting the boundaries a bit, but sufficiently statically typed languages seem to develop two (or more) sublanguages. Global complexity definitely pushes Rust down peg.
Unless I'm mistaken that clears some stuff up for me. Thank you!
---
One benefit is that functions are more reusable. Functions with more arguments can be partially applied and used where applicable.
For instance, if you wanted to increment the values in a list you might do something like this in python:
map(lambda x: x + 1, [1,2,3])
But in an ML like language you can do something like: map((+ 1), [1,2,3])
Because plus is actually a function that takes two arguments and can be curried down to one argument.Additionally, you can think of currying as a form of dependency injection.
For example, if you wanted to inject a database client and a logger before running a query you might do something like this:
def queryer(db, logger):
def _q(query):
logger.info("before query")
results = db.fetch(query)
logger.info("after query")
return results
return _q
rows = queryer(db, logger)(query)
You could write it a bit more simply in this hypothetical ML like language: queryer db logger query =
logger.info("before query")
results = db.fetch(query)
logger.info("after query")
results
MLs don't require parens/commas for function calls, but you can use parens to force a particular execution order. The lines below have the same result, but some produce and execute intermediate curried functions rows = queryer db logger query
rows = (queryer db) logger query
rows = ((queryer db) logger) query
It's a bit contrived, but you have the flexibility to provide some arguments based on the call site rather than the definition site. I.e., the first example was broken up into 2 function calls at the definition site, but the second example could have 1, 2, or 3 function calls.---
I hope this makes sense and I wish I could preview my comment to see if it was formatted reasonably!