---
# System prepended metadata

title: Unison universal serialization

---

# Unison universal serialization

Straw man: 

```Haskell
serialize : a ->{IO} Bytes
deserialize : Bytes ->{IO} Either DecodeError Code

-- Code is a thing that has hashes for references,
-- so it can be serialized / deserialized and mean
-- the same thing everywhere
Code.toValue : Code -> a
Code.dependencies : Code -> [Link]

Code.fromLink : Link ->{Runtime} Code
```

Paul: do we want node servers that are written in pure Unison? Would be nice... but also maybe complicated?
What are alternatives to this?

Dan: is the above even feasible?
Dan: some stuff doesn't make sense to send (like MVar)
  - if A has an MVar locally and you hop from A to B, then back to A, can you reference the MVar
  - maybe just bomb at serialization time?
  - maybe replace with a dummy value that bombs if you ever try to interact with it (this might be better if typechecker would rule this out anyway)
Paul: need some more information so we can negotiate syncing of missing dependencies
Paul: the node server (thing that accepts remote computations and runs them) should have some security so that computations only get access to specified abilities (and not all of `IO`)

```Haskell
ability Remote g task where
  forkAt : Location -> '{Remote g task, g} a -> task a
  await : task a -> a
```

Q: what is the node server going to do?

```Haskell
serve : (forall a . '{g} a ->{IO} a) ->{IO} ()
serve interpret = 
  -- start a tcp server
  -- repeatedly accept connection
  -- from each connection, deserialize:
  --   '{g, Remote g Task} e
  -- protocol will have a forkAt message - 
  --   server locally forks a thread to do the thing,
  --   create a GUID for the task, and will add an 
  --   (GUID, MVar Value) to a "results" map
  --   the thread will write to the MVar when it's done
  --   
  -- await request might hold the connection open
  -- until the MVar is filled, or if it's not filled in
  -- 5s, it might register to be notified
```