> > 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) {
default:
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.
+1
> 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?
Matthias
___
bro-dev mailing list
bro-dev@bro.org
http://mailman.icsi.berkeley.edu/mailman/listinfo/bro-dev