- https://github.com/gleam-lang/gleam/blob/7e2d1f247016a9700a4aa9d9e04b59f7c0a6670f/compiler-core/src/build/package_compiler.rs#L291
- https://github.com/gleam-lang/gleam/blob/7e2d1f247016a9700a4aa9d9e04b59f7c0a6670f/compiler-core/src/build.rs#L58
- https://github.com/gleam-lang/gleam/blob/7e2d1f247016a9700a4aa9d9e04b59f7c0a6670f/compiler-cli/src/build.rs#L22
# WASI
- https://github.com/rustwasm/walrus ([example](https://github.com/rustwasm/walrus/blob/main/examples/build-wasm-from-scratch.rs))
- https://developer.mozilla.org/en-US/docs/WebAssembly/Understanding_the_text_format
- https://crates.io/crates/wat
- https://crates.io/crates/wast
- https://webassembly.github.io/spec/core/bikeshed/#text-format%E2%91%A0
# Python
## Comments
- `///` become function docstrings
- `////` become module docstrings
## Equality
- `==`, `!=` directly translate
- ==Need to make sure all classes implement `__eq__` for structural equality==
## Integers
- Python `int` can be directly used
- `+`, `-`, `//`, `*`, `%`, `>`, `<`, `>=`, `<=` all directly translate
- `_` digit separator directly translates
- `0b`, `0o`, `0x` directly translate
## Floats
- Python `float` directly translates
- `+.`, `-.`, `/.`, `\*.`, `>.`, `<.` , `>=.`, `<=.` translate w/o the `.`
- `_` and `e` directly translate
## Booleans
- Literals directly translates
- `||` → `or`
- `&&` → `and`
- `!` → `not`
## Strings
- Literals should directly translate
- `<>` → `+`
## Tuple
- `#(<items)` → `(<items)`
- `<variable>.<index>` → `<variable>[<index>]`
## Lists
- They will require a custom class
- Make immutable
- `__slots__`
- `__len__`
- ==What to name them in Python due to name clash (e.g., `LinkedList`)?==
- ==Class structure (i.e. how to represent the empty list)?==
- [Scheme](https://www.scheme.org/)-style where there's a separate empty list class and then a pair class for lists w/ >=1 items?
- Gleam JavaScript has a [distinct class for the empty cell](https://github.com/gleam-lang/gleam/blob/1ee481869f141e79702355407f6d6c0919a4a23d/compiler-core/templates/prelude.mjs#L83-L91)
- A class representing an overall list and a separate class for cells/pairs/nodes in the list?
- ==How to do `[<items>, ..<variable>]` prepending?==
- Method?
- `__add__`?
## Types
- Aliases translate to the [`type` statement](https://docs.python.org/3/reference/simple_stmts.html#the-type-statement)
- Custom types translate to a base class for the type and subclasses for the variants
- `__slots__`
- `__match_args__`
- Non-record variants -- i.e. no fields -- _probably_ can be the same as a record variant that takes no arguments for its `__init__`
## `Nil`
- `Nil` → `None`
## `Result`
- Will require a custom class
## Bit arrays
- _Should_ translate to `bytes` with appropriate work to change the literal based on the options specified
## Assignment
- `let <name> = <value>` → `<name> = <value>`
- Type annotation also translates accordingly
- ==What to do about `let assert`?==
- Might need to translate to a `match` statement where successful match has the assignment and a `_` clause that raises an exception (although what exception?)
## Blocks
- ==Will creating a new scope cause issues?==
- Cell variables for a closure might be an issue
## Functions
```gleam
fn <name>(<param>: <type>) -> <return type> { <body> }
```
```Python
def <name>(<param>: <type>) -> <return type>:
<body>
```
- ==How to handle public vs private functions?
- Don't?
- Only differentiate in `__all__`?
- Prefix `_` to non-`pub` functions?
- ==How to handle multi-line, anonymous functions?==
- Might need to hoist to a named function (i.e. [desugar them like lambdas](https://snarky.ca/unraveling-lambda-expressions/))
- ==How to handle closures?==
- The language lets you rebind variable names, but the value of the variable is closed over by the closure
- Compare that to Python where you close over the name instead of the value
- [Function captures](https://tour.gleam.run/functions/function-captures/) can be handled via `lambda`
- Generics should work via [type parameters](https://docs.python.org/3/reference/compound_stmts.html#grammar-token-python-grammar-type_params)
- Labelled arguments which differ from the parameter's inner name will require an explicit assignment at the start of the function body
## Case expressions
- _Should_ translate to [`match` statements](https://docs.python.org/3/reference/compound_stmts.html#grammar-token-python-grammar-match_stmt)
## Import
```gleam
import gleam/io
import gleam/io.{debug}
```
```python
from gleam import io
from gleam.io import debug
```
- ==What to do about `type` imports?==
- Type variant names are exposed without qualification from the `type` itself
- Would need to import all variants and the `type`, but that would require information about the type itself in order to import all the correct names
## Deprecation
- Custom decorator that uses `warnings`
## `todo`
- Raise an exception
## `panic`
- Raise an exception
## Externals
- Treat "file path" as the import path
```gleam
@external(<language>, <file path>, <function name>)
fn <function name>(<args>) -> <return type>
```
```Python
from <file path> import <function name>
```
- The typing is for Gleam's benefit and to model the Python function call signature, so other than bringing the name into scope there isn't anything needed to be done on the Python side
- ==How to handle exceptions?==
- Since this is to service Gleam users, then might not be important since Gleam code itself can't raise an exception
- Probably need to expect Python code to return `Result` as appropriate instead of letting an exception come through (i.e. not our problem, instead the person doing the wrapping needs to do the work)
- Tooling should allow for using Python types and `@external` to generate wrappers in both directions
- Exceptions from wrapping the Python side might be a little tricky, but can probably come up with some bottom `Exception` in Gleam and a `try`/`except Exception` for an entire function which returns `Result<..., Exception>` so there's at least a universal way of managing exceptions on the Gleam side
- Wrapping the Gleam side, it's probably easiest to just stick with `Result` and let Python code deal with it rather than translate `Result` to an exception