[Bro-Dev] [Proposal] Language extensions for better Broker support

Matthias Vallentin vallentin at icir.org
Tue Dec 6 03:17:05 PST 2016

> >   Alternative to even providing “type(v)”, you could have a “v is T”
> I like that. That avoids the question of storing types altogether.

I think we can cover all type-based dispatching with "is" and "switch."
In fact, I see "x is T" as syntactic sugar for:

function is(x: any) {
    switch(x)  {
        return false;
      case T:
        return true;

> > It might even be useful to try and spec out the co-routine support now
> > and see how this specific use-case fits in with that.
> Need to think about that, would clearly be nice if we could pave the
> way for that already. 


> Full enumeration doesn't seem possible, that would mean all possible
> types, no?

Yeah, not in a distributed systems, at least. I think I was coming from
C++ here where dispatching on type-safe unions requires complete
enumeration of all overloads. In Bro, we don't need that because we
cannot know the complete list of types a priori.

> Are we requiring "default" for the standard switch statement? If so, I
> agree it makes sense to do the same here (otherwise, not so sure,
> because of consistency).

Sounds good to me.

> >         if ( type(v) == string )
> I believe you misread this: "string" *is* a type.

Ah, now that makes sense!

> >  - Uplevelling, why do we need type() in the first place? Can't we just
> >    overload the switch statement to work on types as well? Or do you
> >    have other use cases in mind?
> My main other use case was offering if-style comparision as well for
> types (see previous point). But if we do "is" for that, we indeed
> wouldn't need the type() anymore.

Good, I like "is" better than a type function because of readability.

> But explicitly specifying one each time takes away some of the
> simplicity.
> On the other hand, with a default timeout we'd probably need to throw
> runtime errors instead of returning something, and Bro isn't good with
> tons of runtime errors (which could happen here).

How is a timeout different from a failed computation due to a different
reason (e.g., connection failure, store backend error)? I think we need
to consider errors as possible outcomes of *any* asynchronous operation.
More generally, we need well-defined semantics for composing
asynchronous computations. For example, what do we do here?

    # f :: T -> U
    # g :: T
    local x = async f(async g())?

One solution: if g fails, x should contain g's error---while f will
never execute. But in the common case of success, the user just wants to
work with x as an instance of T, e.g., when T = count:

    count y = 42;
    print x + y; # use x as type count

If x holds an error, then Bro would raise a runtime error in the
addition operator. Would that make sense?


More information about the bro-dev mailing list