[nem-en] recursive types

Kamil Skalski nazgul at nemerle.org
Thu Sep 23 13:42:57 CEST 2004


On Thu, Sep 23, 2004 at 12:52:59PM +0200, Wiktor Zychla wrote:
> >Pattern variables need to be lowercase[1]. The error message should be
> >improved, so it's again a bug -- please report it.
> 
> 1. again, what's wrong with above code?
> 
> using System;
> 
> variant Lambda {
> | Abs { name : Id; term : Lambda; }
> | App { term1 : Lambda; term2 : Lambda; }
> | Id { name : string; }
> }
> }
> 
> class Hello
> {
> static Main() : void
> {
>  mutable l = Abs( Id( "x" ), App( Id( "x" ), Id( "y" ) ) );   // error
>  Console.WriteLine( l );
> }
> }
> 
> in arg #1 needed Id got Lambda calling a reference to global symbol 
> `Abs..ctor'

Actually this is the weakness of our current typesystem (changes are
coming soon). Constructor of variant option returns object of variant
type. So here Id ("x") : Lambda, not Id as you could think. But this
is only because compiler ignore real type of Id and immediately
thinks it is Lambda. It is to allow easily [Id ("d"), Abs(..)] :
list<Lambda> 

http://www.nemerle.org/bugs/bug_view_page.php?bug_id=0000115

You can cast Id to Id:
 Abs( Id( "x" ) :> Id, App( Id( "x" ), Id( "y" ) ) ); 

> 
> does it mean that self-referencing types between branches in the definition 
> of a variant variant type confuses the compiler (Id branch is referenced in 
> Abs branch)?

Actually not quite. But for now it is probably better to use variant
type, not variant options' types.

> 
> 2. do you think that it would be it possible to allow:
> 
> variant Lambda {
> | Abs { name : string; term : Lambda; }
> | App { term1 : Lambda; term2 : Lambda; }
> | name : string;
> [it does not compile]

If possible, it would be neccesary to place it inside some implicitly 
created option, like:
| _N_name { name : string; }

Uppercase would be also needed. I don't know how much would it 
complicate matching engine, but IMHO it is a nice feature.

> 
> instead of
> 
> variant Lambda {
> | Abs { name : Id; term : Lambda; }
> | App { term1 : Lambda; term2 : Lambda; }
> | Id { name : string; }
> 
> and then simply:
> 
>    match( this ) {
>        | Abs( ... ) =>
>        | App( ... ) =>
>        | name : string =>
>    }

You would have to write | Id (name) => in current system.

Thanks for taking a look at compiler and feedback.

Kamil




More information about the devel-en mailing list