From: joel de guzman (djowel_at_[hidden])
Date: 2002-04-13 05:22:59
This is nice Doug. I really like your hidden agenda. Just 2 questions:
1) Well, the <|> operator is nice, but wouldn't the <,> operator
be more C++ like? Either way, it's nice.
2) If LL moves on to switch_(expr)[...] syntax, which I think will happen,
might there be an ambiguity? What sub-namespace will this switch on
variant type be in? variant::switch_(v) ?
Kudos! I wish for something like this a lot.
----- Original Message -----
From: "Douglas Gregor" :
> We've talked about adding a switch-on-type construct for a while, so I
> thought I'd whip up a prototype that we could talk about. The prototype is
> here, but read on:
> Here are some requirements that I personally have for a switch-on-type
> construct, which are, of course, open for debate:
> 1) Syntactically similar to a C++ switch() statements. I think Phoenix-like
> syntax is the way to go, here.
> 2) Ability to return a value from a typeswitch. This makes it possible for
> essentially pattern-based transformation systems. (My hidden goal here is to
> simplify AST transformations).
> 3) Some form of pattern matching or decomposition of simple product (e.g.,
> tuple) types, so that if our type contains two elements in it, they will be
> the first and second arguments to the function object processing a value of
> that type.
> 4) Not tied to any particular sum (variant, union, discriminated union,
> etc.) or product (tuple, class, typelist, etc) type (any functional
> programming gurus want to correct my terminology? FP isn't my area...). Any
> type should be adaptable to one or both categories.
> 5) Safety checks for completeness of decoding, unmatchable clauses, etc.
> 6) Handle both tagged and untagged clauses (e.g., an Ocaml-like variant has
> tags that may or may not have value types associated with them, whereas
> boost::any is untagged)
> Here's a short example that (I believe) should illustrate how I envision a
> int compute(any expr)
> using namespace boost::lambda;
> return switch_<int>(expr)[
> case_<Literal>((_1, _1))
> | case_<Add>(bind(&compute, _1) + bind(&compute, _2))
> | case_<Sub>(bind(&compute, _1) - bind(&compute, _2))
> | case_<Mul>(bind(&compute, _1) * bind(&compute, _2))
> | case_<Div>(bind(&compute, _1) / bind(&compute, _2))
> The behavior of the code is, I hope, obvious: it takes a representation of an
> expression, built from integer literals and the binary operations Add, Sub,
> Mul, and Div, and computes the value of the expression recursively. Some
> notes on how this works:
> - The operators are product types, so an 'Add' contains two subexpressions
> for its operands. When 'Add' is matched, it is decomposed into the two
> subexpressions and those are passed as individual arguments to the supplied
> function object. If you're an Ocaml person, think of 'Add' being equivalent
> Add of Expression * Expression
> And the "| case_<Add>(do_something)" is:
> | Add(_1, _2) -> do_something(_1, _2)
> - The sum type used is boost::any. I added a specialization of the
> 'sum_traits' type trait for boost::any, but did not change any other source
> code in boost::any.
> - The product type used is boost::tuples::tuple. I added a specialization
> of the 'product_traits' type trait for boost::tuples::tuple, but did not
> change any other source code in the tuples library.
> - The Lambda library is used for the operator syntax. The actual source
> file this came from (libs/type_switch/compute.cpp in the archive) can also
> use Boost.Bind, if you don't have Lambda around..
> - I pulled a few dirty tricks to fake tag types with boost::any. Basically,
> each tag (e.g., 'Add') is a class that derives from the appropriate tuple
> type (boost::tuples::tuple<boost::any, boost::any>) and has a product_traits
> specialization that forwards the tuple product_traits information. With a
> tagged variant type, this hackery would all disappear but the code above
> would remain the same.
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk