# Listly

Lisp-style property lists and association lists for LFE.

Listly deliberately keeps the two representations separate:

* `plist` is a flat list of alternating keys and values, such as `(:name "Alice" :age 30)`.
* `alist` is a list of two-item associations, such as `((name "Alice") (age 30))`.

Both modules are implemented in LFE and expose ordinary BEAM modules that LFE or Elixir can call. The project includes the small `mix_lfe`-compatible compiler integration needed by current Mix and LFE releases.

## Development

```sh
nix develop
mix deps.get
mix compile
mix test
```

The checked-in integration suite runs with `mix test` and calls the compiled LFE modules directly.

## Semantics

Lookups are linear and return the first matching occurrence. Duplicate keys are retained. `put` replaces the first matching entry while preserving its position; absent entries are added at the front. `remove` removes every matching entry.

`plist` validates its input before every public operation. An odd-length or improper property list returns `{error, malformed-plist}`. `alist:to-plist/1` returns `{error, malformed-alist}` when an entry is not a two-item list; other alist operations skip malformed entries during searches and collection.

## Examples

```lisp
(plist:get '(:name "Alice" :active false) ':name)
;; => "Alice"

(plist:put '(:name "Alice") ':age 30)
;; => (:name "Alice" :age 30)

(alist:assoc 'name '((name "Alice") (name "Bob")))
;; => (name "Alice")

(alist:pairlis '(name age) '("Alice" 30))
;; => ((name "Alice") (age 30))
```
