'Examples
>>> from blaze import symbol
>>> t = symbol(\'t\', \'var * {name: string, amount: int}\')
>>> s = symbol(\'t\', \'var * {name: string, id: int}\')
>>> join(t, s).schema
dshape("{name: string, amount: int32, id: int32}")
>>> join(t, s, how=\'left\').schema
dshape("{name: string, amount: int32, id: ?int32}")
Overlapping but non-joined fields append _left, _right
>>> a = symbol(\'a\', \'var * {x: int, y: int}\')
>>> b = symbol(\'b\', \'var * {x: int, y: int}\')
>>> join(a, b, \'x\').fields
[\'x\', \'y_left\', \'y_right\']'

def _schema(self):

    option = (lambda dt: (dt if isinstance(dt, Option) else Option(dt)))
    on_left = self.on_left
    if (not isinstance(on_left, list)):
        on_left = (on_left,)
    on_right = self.on_right
    if (not isinstance(on_right, list)):
        on_right = (on_right,)
    right_types = keymap(dict(zip(on_right, on_left)).get, self.rhs.dshape.measure.dict)
    joined = ((name, promote(extract_key(dt), extract_key(right_types[name]), promote_option=False)) for (n, (name, dt)) in enumerate(filter(compose(op.contains(on_left), first), self.lhs.dshape.measure.fields)))
    left = [(name, dt) for (name, dt) in zip(self.lhs.fields, types_of_fields(self.lhs.fields, self.lhs)) if (name not in on_left)]
    right = [(name, dt) for (name, dt) in zip(self.rhs.fields, types_of_fields(self.rhs.fields, self.rhs)) if (name not in on_right)]
    left_other = set((name for (name, dt) in left if (name not in on_left)))
    right_other = set((name for (name, dt) in right if (name not in on_right)))
    overlap = (left_other & right_other)
    (left_suffix, right_suffix) = self.suffixes
    left = ((((name + left_suffix) if (name in overlap) else name), dt) for (name, dt) in left)
    right = ((((name + right_suffix) if (name in overlap) else name), dt) for (name, dt) in right)
    if (self.how in ('right', 'outer')):
        left = ((name, option(dt)) for (name, dt) in left)
    if (self.how in ('left', 'outer')):
        right = ((name, option(dt)) for (name, dt) in right)
    return dshape(Record(chain(joined, left, right)))
