Actually value constructors are first class, and you can pass them as values in Haskell as far as I remember.
Keean. On 31 May 2015 17:42, "Jonathan S. Shapiro" <s...@eros-os.org> wrote: > > On Sat, May 30, 2015 at 5:17 PM, Matt Oliveri <atma...@gmail.com> wrote: >> >> On Sat, May 30, 2015 at 5:28 PM, Jonathan S. Shapiro <s...@eros-os.org> wrote: >> > Let me show the part I don't know how to do in any current language. >> > >> > Assume we have a templated structure ASTNode<T>. It has a children field. >> > The intent is that the child field will be some structured type (a record or >> > a product). Depending on the type T, we want the type of the "child" field >> > to be different. >> > >> > I suppose we could do this with a family of AST structures, e.g. where T is >> > the record type itself. So we might have >> > >> > struct Expr { >> > ASTNode<Expr> * e1; >> > ASTNode<Expr> *e2; >> > } >> > >> > struct ASTNode<T> { >> > ... common fields ... >> > T children; >> > } >> >> Where did all the other union legs go? I guess this is C++ now, and >> those can be defined separately. > > > Well, my intent here was that each type of AST would have it's own struct similar to struct Expr. > >> >> > though this doesn't seem to handle any of the "subunion" cases in a way I >> > can obviously see. >> >> Right. The Node trick just factors out the common fields. It doesn't >> give you your subunions. I wasn't aware you'd need that from the >> problem description from about a week ago. > > > Right. The problem description was intentionally simplified. I don't see how to do it even if we ignore the entire subunion thing. > >> >> > Except I'm not sure that we can forward-reference a >> > template in this way. >> >> Right. ASTNode should've gone before Expr. > > > The dependency is cyclic. We either need a way to forward-declare ASTNode<T>, or we need a way to define the entire set of types as mutually co-recursive. > >> >> Anyway, why does this problem keep switching languages? At first I >> thought you were doing something in F#, then I showed it in OCaml, now >> today for a while I thought you wanted to be able to do it in BitC, >> and now you're talking about templates from C++. > > > I went to C++ because you introduced ASTNode<T>, so I assumed you were talking about C++ templates. Sorry if I misunderstood you. And I agree that C++ is a uniquely bad language to talk about this in. > > But here's the key point to keep in mind: > > In OCaml, F#, and Haskell, value constructors are not procedures. You cannot pass them as parameters. Also (at least in these languages) union leg constructors are not types. You cannot use a leg constructor name to instantiate a type variable. Because of this, I'm not seeing how parameterization tricks in *any* of these languages get us anywhere. > > It's clear to me that we *could* design a language in which these things *are* types, and it's clear to me that there are some valid use-cases for doing so. I'm just not sure that there are *enough* valid use cases to be worth bothering. > >> >> While I am saying that you should be able to do this (factoring with >> Node, not subunion) in any of those, I don't know if it'd be a good >> way to do it in any of those except OCaml. > > > Fair enough. Though note that without subunion (or something that serves a similar function) we can't really express ASTs with static typing. Ultimately we either have to deal with the fact that > > expr == mulexpr | divexpr | addexpr | subexpr > > or we have to deal with a lot of unnecessary case legs and weak checking of the tree hierarchy. If we have to accept weak checking, we aren't getting much value out of the static typing for validating the construction of the tree. > > Just to be clear: this may very well be a case where it isn't worth the bother to push static types this hard. > > >> >> >> > Even if we can, it begs the question of how to specialize the member >> > functions of ASTNode, which need to do different things depending on how T >> > was instantiated. We really don't want do this by using a distinct function >> > for each type T. >> >> Back when I recommended it, Node was just an alias for a tuple type. >> No member functions. If the AST were to be a variant datatype, it >> wouldn't technically have member functions either. I showed how you'd >> define a function by pattern matching on Node and then the children >> field (which didn't have a name at the time). >> >> If you're doing this in a class-oriented way, I wouldn't recommend Node at all. > > > Whether the functions are member functions or global functions isn't really the point. That's just syntactic sugar. The point is that we probably don't want to have to write a distinct function for each variant of the Node type. It's too difficult in practice to maintain things that way. > > > shap > > _______________________________________________ > bitc-dev mailing list > bitc-dev@coyotos.org > http://www.coyotos.org/mailman/listinfo/bitc-dev >
_______________________________________________ bitc-dev mailing list bitc-dev@coyotos.org http://www.coyotos.org/mailman/listinfo/bitc-dev