def member(item, x):
    return (None if is_none(x)
            else x if item == head(x)
            else member(item, tail(x)))
def for_each_except(exception, fun, list):
    def loop(items):
        if is_none(items):
            return "done"
        elif head(items) is exception:
            return loop(tail(items))
        else:
            fun(head(items))
            return loop(tail(items))
    return loop(list)
def inform_about_value(constraint):
    return constraint("I have a value.")

def inform_about_no_value(constraint):
    return constraint("I lost my value.")
def has_value(connector):
    return connector("has_value")

def get_value(connector):
    return connector("value")

def set_value(connector, new_value, informant):
    return connector("set_value")(new_value, informant)

def forget_value(connector, retractor):
    return connector("forget")(retractor)

def connect(connector, new_constraint):
    return connector("connect")(new_constraint)
def make_connector():
    value = False
    informant = False
    constraints = None
    def set_my_value(newval, setter):
        nonlocal value, informant
        if not has_value(me):
            value = newval
            informant = setter
            return for_each_except(setter,
                                   inform_about_value,
                                   constraints)
        elif value != newval:
            error("contradiction", llist(value, newval))
        else:
            return "ignored"
    def forget_my_value(retractor):
        nonlocal informant
        if retractor is informant:
            informant = False
            return for_each_except(retractor,
                                   inform_about_no_value,
                                   constraints)
        else:
            return "ignored"
    def connect(new_constraint):
        nonlocal constraints
        if is_none(member(new_constraint, constraints)):
            constraints = pair(new_constraint, constraints)
        else:
            pass
        if has_value(me):
            inform_about_value(new_constraint)
        else:
            pass
        return "done"
    def me(request):
        if request == "has_value":
            return informant is not False
        elif request == "value":
            return value
        elif request == "set_value":
            return set_my_value
        elif request == "forget":
            return forget_my_value
        elif request == "connect":
            return connect
        else:
            error("unknown operation -- connector", request)
    return me
