From nickle@nickle.org  Sun Aug  4 04:18:33 2002
From: nickle@nickle.org (Keith Packard)
Date: Sat, 03 Aug 2002 20:18:33 -0700
Subject: [Nickle]Array comprehension syntax
Message-ID: <E17bBub-00017c-00@localhost>

Array comprehensions are lambdas evaluated to initialize an array; they're 
passed the index of the desired element and compute that element.  
Essentially, they're a shorthand notation for:

    int[*,*]	a = [2, 2];

    for (int i = 0; i < 2; i++)
	for (int j = 0; j < 2; j++)
	    a[i,j] = lambda (i,j);

I've got the underlying code all built for compiling and executing these,
but I'm a bit stuck on the syntax.  My current (lame) syntax looks like:

    int[*,*]	a = [2, 2] { = int func (int i, int j) { return i*j; } };

Actually, any expression which evaluates to a function can be used inside
the initializer:

    int c (int i, int j) { return i * j; }
    
    int[*,*]	a = [2, 2] { = c };

I'm really not excited about this syntax and am looking for suggestions.
However, even with this weak syntax, compose looks a lot nicer:

    poly (poly...) compose (poly f, poly g) {
        return poly func (poly args...) {
            poly(int) pick(int start) {
                return func (int i) { return args[start+i]; };
            }
            return f (g ((poly[func_args(g)]) { = pick(0) } ...),
                      (poly[func_args(f)-1]) { = pick(func_args(g)) }...);
        };
    }

The only problem is that the arguments 'f' and 'g' aren't statically
typechecked to accept only functions.  We don't have any syntax for
a function which takes an arbitrary number of arguments, all we have
is syntax for a function which takes a variable number of arguments;
the problem is that:

	poly(poly...) a = poly func (poly g) { return g; }

is currently a type error (Incompatible types 'poly(poly ...)', 'poly(g)')

We need a formal spec for our current type system...

-keith




From nickle@nickle.org  Mon Aug  5 07:34:03 2002
From: nickle@nickle.org (Bart Massey)
Date: Sun, 04 Aug 2002 23:34:03 -0700
Subject: [Nickle]Array comprehension syntax
In-Reply-To: Your message of "Sat, 03 Aug 2002 20:18:33 PDT."
 <E17bBub-00017c-00@localhost>
Message-ID: <E17bbRL-0006Sf-00@bart.cs.pdx.edu>

My principal syntactic objection are that both the formal
and result types of the comprehension func, together with
the fact that it's a func and its arity, are already known.
Thus, the explicit func() is inappropriate: the
comprehension should just take formal names and an
expression, like the Smalltalk block construct.

Perhaps something like
  int[10,10] a = { =(i,j) i * j ... };
is not too bad?  Note that this syntax might also allow
things like
  int[10] a = { =(i) i + 1, =(i) i + 2, =(j) j * j ... };
although I can't for the life of me figure out how this
would be useful :-).

Note also that if you want a lambda for structure it's not a
big deal to have one:
  int[11] a = { =(i)
    int func(int j) {
       if (j < 5)
           return j;
       return 10 - j;
    } (i) ... };
although arguably better here is
  int[11] a = { =(i) ({ if (i < 5) return i; return 10 - i; }) ... };
and arguably better still is
  int triangle(int n, int i) {
     int b = n // 2;
     if (i < b)
         return i;
     return 2 * b - i;
  }
  int[11] a = { =(i) triangle(11, i) ... };
although in all these examples it is troubling that changing
the size of a will not automatically work, so maybe
  int[11] a = { =(i) triangle(dim(a), i) ... };
works, although I don't think a is scoped in yet in the
initializer :-) so probably not.  Sigh.
  
The other classic approach is to not let the user name the
formals, but instead pre-supply names: something like
  int[11] a = { = triangle($#, $1) ... };
or perhaps something less ugly.

	Bart

In message <E17bBub-00017c-00@localhost> you wrote:
> 
> Array comprehensions are lambdas evaluated to initialize an array; they're 
> passed the index of the desired element and compute that element.  
> Essentially, they're a shorthand notation for:
> 
>     int[*,*]	a = [2, 2];
> 
>     for (int i = 0; i < 2; i++)
> 	for (int j = 0; j < 2; j++)
> 	    a[i,j] = lambda (i,j);
> 
> I've got the underlying code all built for compiling and executing these,
> but I'm a bit stuck on the syntax.  My current (lame) syntax looks like:
> 
>     int[*,*]	a = [2, 2] { = int func (int i, int j) { return i*j; } };
> 
> Actually, any expression which evaluates to a function can be used inside
> the initializer:
> 
>     int c (int i, int j) { return i * j; }
>     
>     int[*,*]	a = [2, 2] { = c };
> 
> I'm really not excited about this syntax and am looking for suggestions.
> However, even with this weak syntax, compose looks a lot nicer:
> 
>     poly (poly...) compose (poly f, poly g) {
>         return poly func (poly args...) {
>             poly(int) pick(int start) {
>                 return func (int i) { return args[start+i]; };
>             }
>             return f (g ((poly[func_args(g)]) { = pick(0) } ...),
>                       (poly[func_args(f)-1]) { = pick(func_args(g)) }...);
>         };
>     }
> 
> The only problem is that the arguments 'f' and 'g' aren't statically
> typechecked to accept only functions.  We don't have any syntax for
> a function which takes an arbitrary number of arguments, all we have
> is syntax for a function which takes a variable number of arguments;
> the problem is that:
> 
> 	poly(poly...) a = poly func (poly g) { return g; }
> 
> is currently a type error (Incompatible types 'poly(poly ...)', 'poly(g)')
> 
> We need a formal spec for our current type system...
> 
> -keith
> 
> 
> 
> _______________________________________________
> Nickle mailing list
> Nickle@nickle.org
> http://nickle.org/mailman/listinfo/nickle


From nickle@nickle.org  Tue Aug  6 03:11:36 2002
From: nickle@nickle.org (Keith Packard)
Date: Mon, 05 Aug 2002 19:11:36 -0700
Subject: [Nickle]Array comprehension syntax
In-Reply-To: Your message of "Sun, 04 Aug 2002 23:34:03 PDT."
 <E17bbRL-0006Sf-00@bart.cs.pdx.edu>
Message-ID: <E17btou-0000MO-00@localhost>

Around 23 o'clock on Aug 4, Bart Massey wrote:

> the comprehension should just take formal names and an expression, like the
> Smalltalk block construct.

How about two forms:

 a)	{ = (i, j) i * j }

 b)	{ = (i, j) { return i * j; } }

These are trivial to distinguish, although my compose example does
take advantage of the ability to use an arbitrary function valued 
expression as a comprehension which I thought was a pretty nifty trick.

Here's what compose would look like with form a):

    poly (poly...) compose (poly f, poly g) {
        return poly func (poly args...) {
            return f (g ((poly[func_args(g)]) { = (i) args[i] } ...),
                      (poly[func_args(f)-1]) { = (i) args[func_args(g)+i] }...);
        };
    }

It's getting shorter and shorter...

Keith Packard        XFree86 Core Team        HP Cambridge Research Lab




From nickle@nickle.org  Tue Aug  6 03:18:59 2002
From: nickle@nickle.org (Keith Packard)
Date: Mon, 05 Aug 2002 19:18:59 -0700
Subject: [Nickle]Array comprehension syntax
In-Reply-To: Your message of "Sun, 04 Aug 2002 23:34:03 PDT."
 <E17bbRL-0006Sf-00@bart.cs.pdx.edu>
Message-ID: <E17btw3-0000Ms-00@localhost>

Around 23 o'clock on Aug 4, Bart Massey wrote:

>   int[11] a = { =(i) triangle(11, i) ... };
> although in all these examples it is troubling that changing
> the size of a will not automatically work, so maybe
>   int[11] a = { =(i) triangle(dim(a), i) ... };
> works, although I don't think a is scoped in yet in the
> initializer :-) so probably not.  Sigh.

The variable 'a' is scoped in, but it hasn't been initialized yet.
That follows the L-to-R rule for evaluation; the declaration is to the 
left of the initializer so the variable is in scope, but the initializer 
is the RHS of the assignment operator which hasn't been evaluated yet so
a is uninitialized.  I'm wondering if we'd like a syntax that permitted 
reflexive comprehensions; I could scope in some magic name which referred 
to the array itself within the context of the anonymous lambda.

> The other classic approach is to not let the user name the
> formals, but instead pre-supply names: something like
>   int[11] a = { = triangle($#, $1) ... };
> or perhaps something less ugly.

Yuck.  Positional arguments deemed harmful.

Keith Packard        XFree86 Core Team        HP Cambridge Research Lab




From nickle@nickle.org  Wed Aug  7 08:39:41 2002
From: nickle@nickle.org (Keith Packard)
Date: Wed, 07 Aug 2002 00:39:41 -0700
Subject: [Nickle]New suggestion for comprehensions
Message-ID: <E17cLQ1-0000yR-00@localhost>

	a) (int[10]) { [i] = i + 1 }

	b) (int[10]) { [i] { return i + 1; } }

Should b) get an '=' operator as well?

This syntax requires a small sacrifice elsewhere in the grammar:

	[10] { 1 ... }

is currently valid, and generates a 10 element array of type poly.  This 
would need to be:

	([10]) { 1 ... }

which is (somewhat) more symmetrical with:

	(poly[10]) { 1 ... }

but has the disadvantage of nesting brackets...

Keith Packard        XFree86 Core Team        HP Cambridge Research Lab




From nickle@nickle.org  Wed Aug  7 09:02:59 2002
From: nickle@nickle.org (Keith Packard)
Date: Wed, 07 Aug 2002 01:02:59 -0700
Subject: [Nickle]New function syntax
Message-ID: <E17cLmV-00012A-00@localhost>

Poking at comprehensions yielded an interesting new syntax for functions:

	int foo (int i) = i + 1;

Nice and compact; makes some programming styles much prettier.

-keith




From nickle@nickle.org  Wed Aug  7 09:09:10 2002
From: nickle@nickle.org (Bart Massey)
Date: Wed, 07 Aug 2002 01:09:10 -0700
Subject: [Nickle]New function syntax
In-Reply-To: Your message of "Wed, 07 Aug 2002 01:02:59 PDT."
 <E17cLmV-00012A-00@localhost>
Message-ID: <E17cLsU-0008UP-00@bart.cs.pdx.edu>

In message <E17cLmV-00012A-00@localhost> you wrote:
> Poking at comprehensions yielded an interesting new syntax for functions:
> 	int foo (int i) = i + 1;

In
	poly() foo = f;
it is unclear to me whether f is an initializer for foo or an
expression defining it.  Note that it matters.

Besides, I don't want to be gratuitously incompatible with
C, even where C is wartsy...

	Bart


From nickle@nickle.org  Wed Aug  7 09:36:29 2002
From: nickle@nickle.org (Keith Packard)
Date: Wed, 07 Aug 2002 01:36:29 -0700
Subject: [Nickle]New function syntax
In-Reply-To: Your message of "Wed, 07 Aug 2002 01:09:10 PDT."
 <E17cLsU-0008UP-00@bart.cs.pdx.edu>
Message-ID: <E17cMIv-0001HT-00@localhost>

Around 1 o'clock on Aug 7, Bart Massey wrote:

> 	poly() foo = f;
> it is unclear to me whether f is an initializer for foo or an
> expression defining it.  Note that it matters.

The = expr syntax only applies to the sugared version of function 
declarations

	poly foo () = f;

The unsugared version remains:

	poly() foo = poly func () { return f; }

> Besides, I don't want to be gratuitously incompatible with
> C, even where C is wartsy...

It's just a terse form for a very common function style, especially when
coding in a functional style.

Keith Packard        XFree86 Core Team        HP Cambridge Research Lab




From nickle@nickle.org  Fri Aug  9 23:13:48 2002
From: nickle@nickle.org (Keith Packard)
Date: Fri, 09 Aug 2002 15:13:48 -0700
Subject: [Nickle]Array comprehension changes
Message-ID: <E17dI0y-0000jY-00@localhost>

Carl came up with the improved syntax which now works:

	a)	int[10] i = { [j] = j + 1 };
	b)	int[10] i = { [j] { 
				int c = 0;
				for (int k = 0; k <= j; k++) 
					c += k;
				return c;
			} };

Bart asked for a way to name the array inside the comprehension, so I came 
up with '[]':

		int[10] i = { [j] = dim([]) - j };

-keith




From nickle@nickle.org  Sat Aug 10 01:07:13 2002
From: nickle@nickle.org (Bart Massey)
Date: Fri, 09 Aug 2002 17:07:13 -0700
Subject: [Nickle]Array comprehension changes
In-Reply-To: Your message of "Fri, 09 Aug 2002 15:13:48 PDT."
 <E17dI0y-0000jY-00@localhost>
Message-ID: <E17dJmj-0000ZG-00@bart.cs.pdx.edu>

Like the comprehension syntax.  Cool!

I must have been drunk when I suggested being able to name
the array inside the comprehension: its a very "special"
case, and the syntax is no good.  Rip it back out, IMHO.

	Bart

In message <E17dI0y-0000jY-00@localhost> you wrote:
> 
> Carl came up with the improved syntax which now works:
> 
> 	a)	int[10] i = { [j] = j + 1 };
> 	b)	int[10] i = { [j] { 
> 				int c = 0;
> 				for (int k = 0; k <= j; k++) 
> 					c += k;
> 				return c;
> 			} };
> 
> Bart asked for a way to name the array inside the comprehension, so I came 
> up with '[]':
> 
> 		int[10] i = { [j] = dim([]) - j };
> 
> -keith
> 
> 
> 
> _______________________________________________
> Nickle mailing list
> Nickle@nickle.org
> http://nickle.org/mailman/listinfo/nickle


From nickle@nickle.org  Fri Aug 16 05:43:08 2002
From: nickle@nickle.org (Bart Massey)
Date: Thu, 15 Aug 2002 21:43:08 -0700
Subject: [Nickle]Slight new stuff, error message buglet
Message-ID: <E17fYx3-0004PA-00@bart.cs.pdx.edu>

max and min builtins have been added to Nickle now.
Functional syntax, one or more arguments.

A libc "ctype" lookalike has been added.  ASCII-only, which
is a bug: should be Unicode.  Namespace Ctype, the obvious
functions.

Error message buglet:

  ->     while (!a[na - 1])
  polynomial.5c:66: Incompatible type, value 'coefficient', for u^A operation

The error is correct, the message needs help.  I will let
Keith chase through the parse tree forest.

	Bart


From nickle@nickle.org  Fri Aug 16 06:54:16 2002
From: nickle@nickle.org (Bart Massey)
Date: Thu, 15 Aug 2002 22:54:16 -0700
Subject: [Nickle]help command for debug mode
Message-ID: <E17fa3s-0004XJ-00@bart.cs.pdx.edu>

Added a very primitive help command to Nickle debug mode.
(Wanted to do it in Nickle, but couldn't see how to extend
the debug mode command set except in C, so I did that
instead.)

	Bart


From nickle@nickle.org  Fri Aug 16 09:28:06 2002
From: nickle@nickle.org (Bart Massey)
Date: Fri, 16 Aug 2002 01:28:06 -0700
Subject: [Nickle]initializer bug
Message-ID: <E17fcSk-0004mq-00@bart.cs.pdx.edu>

Nickle doesn't handle repeated initializers for zero length
arrays correctly...

  bart @ ./nickle
  > int[0] a = {};
  > int[0] a = {0...};
  Unhandled exception "invalid_array_bounds"
	  "Array index out of bounds"
	  [0] {}
	  0
  >

I can see where the code in execute.c is going wrong, but
not what the right fix is.  Yes, this case is important :-(.

	Bart


From nickle@nickle.org  Fri Aug 16 16:53:43 2002
From: nickle@nickle.org (Keith Packard)
Date: Fri, 16 Aug 2002 08:53:43 -0700
Subject: [Nickle]initializer bug
In-Reply-To: Your message of "Fri, 16 Aug 2002 01:28:06 PDT."
 <E17fcSk-0004mq-00@bart.cs.pdx.edu>
Message-ID: <E17fjPz-0001Ud-00@localhost>

Around 1 o'clock on Aug 16, Bart Massey wrote:

> Nickle doesn't handle repeated initializers for zero length
> arrays correctly...

Yeah, it (incautiously) assumed that any repeated initializer was going to 
be used for at least one element.  Fixing that required a change to the 
virtual machine to check the repeat count before doing the first 
initialization.

-keith







From nickle@nickle.org  Sat Aug 17 07:36:41 2002
From: nickle@nickle.org (Bart Massey)
Date: Fri, 16 Aug 2002 23:36:41 -0700
Subject: [Nickle]polytime primes and polynomials
Message-ID: <E17fxCT-0005mp-00@bart.cs.pdx.edu>

For your amusement and edification.  I've implemented and
checked into the Nickle distribution examples directory the
newly-announced polytime primality test due to Agrawal,
Kayal, and Saxena.  It may be polytime, but boy is it slow:
n^6 is nothing to sneeze at.  OTOH, it only took about 6-8
hours of coding including fixing Nickle bugs and misfeatures
and implementing infrastructure: I wouldn't even want to try
it in any other language I'm aware of.  is-prime.5c runs the
primality test for successive integers (with brute force for
integers smaller than some bound, currently 50), and checks
it against the Miller-Rabin BPP test I implemented long ago.

In the process of implementing this, I needed to do
arithmetic on fields mod integer-coefficient polynomials, so
I implemented integer-coefficient polynomials as well.  (The
implementation could be easily altered to have rational or
modular coefficients, but there are deep language waters
here: language design suggestions around parameterizing this
would be received with interest.)  polynomial.5c has the
functionality.

Have fun!

	Bart


From nickle@nickle.org  Sun Aug 18 23:21:03 2002
From: nickle@nickle.org (Keith Packard)
Date: Sun, 18 Aug 2002 15:21:03 -0700
Subject: [Nickle]polytime primes and polynomials
In-Reply-To: Your message of "Fri, 16 Aug 2002 23:36:41 PDT."
 <E17fxCT-0005mp-00@bart.cs.pdx.edu>
Message-ID: <E17gYPv-0002Mo-00@localhost>

Around 23 o'clock on Aug 16, Bart Massey wrote:

> For your amusement and edification.  I've implemented and
> checked into the Nickle distribution examples directory the
> newly-announced polytime primality test due to Agrawal,
> Kayal, and Saxena.

I can't find these in the CVS tree; did CVS get confused?

-keith





From nickle@nickle.org  Mon Aug 19 02:02:23 2002
From: nickle@nickle.org (Bart Massey)
Date: Sun, 18 Aug 2002 18:02:23 -0700
Subject: [Nickle]polytime primes and polynomials
In-Reply-To: Your message of "Sun, 18 Aug 2002 15:21:03 PDT."
 <E17gYPv-0002Mo-00@localhost>
Message-ID: <E17gaw3-0000ee-00@bart.cs.pdx.edu>

I added them, but forgot to commit.  I hate CVS.  Fixed.
Sorry.

	Bart

In message <E17gYPv-0002Mo-00@localhost> you wrote:
> 
> Around 23 o'clock on Aug 16, Bart Massey wrote:
> 
> > For your amusement and edification.  I've implemented and
> > checked into the Nickle distribution examples directory the
> > newly-announced polytime primality test due to Agrawal,
> > Kayal, and Saxena.
> 
> I can't find these in the CVS tree; did CVS get confused?
> 
> -keith
> 
> 
> 
> 
> _______________________________________________
> Nickle mailing list
> Nickle@nickle.org
> http://nickle.org/mailman/listinfo/nickle


From nickle@nickle.org  Thu Aug 29 05:41:22 2002
From: nickle@nickle.org (Bart Massey)
Date: Wed, 28 Aug 2002 21:41:22 -0700
Subject: [Nickle]initializer bug?
Message-ID: <E17kH7S-00019X-00@bart.cs.pdx.edu>

Attached is a code fragment initializing an array of
structures containing an array: the initializer doesn't
work.  Is this a bug in my code, or in Nickle?  I suspect
the latter.  (Additionally, why should Nickle need the
"(cell)" in the initializer?  It seems like it should be
able to infer this from the lhs type, as does C, but it
seems to get even more lost without it.)

Thanks,

	Bart

  /*
   * Ricochet Robots solver
   * Bart Massey 2002/8
   */

  int size = 16;

  typedef enum {
      BLANK, ME, DRONE, TARGET
  } cellval;

  typedef struct {
      cellval val;
      /* 0 == N, 1 == E, 2 == S, 3 == W */
      bool[4] wall;
  } cell;

  cell[size, size] cells = {
      {(cell){val = cellval.BLANK,  wall = {false ...}} ...}
      ...
  };



From nickle@nickle.org  Thu Aug 29 06:57:40 2002
From: nickle@nickle.org (Bart Massey)
Date: Wed, 28 Aug 2002 22:57:40 -0700
Subject: [Nickle]Re: initializer bug?
In-Reply-To: Your message of "Wed, 28 Aug 2002 21:41:22 PDT."
 <E17kH7S-00019X-00@bart.cs.pdx.edu>
Message-ID: <E17kIJI-0001Bg-00@bart.cs.pdx.edu>

Nevermind.  Changing the initialization to

  cell[size, size] cells = {
      {(cell){val = cellval.BLANK,  wall = (bool[4]){false ...}} ...}
      ...
  };

seems to have done the trick.  Frustrating that it has
enough information to typecheck but not to parse, though.

	Bart

In message <E17kH7S-00019X-00@bart.cs.pdx.edu> you wrote:
> Attached is a code fragment initializing an array of
> structures containing an array: the initializer doesn't
> work.  Is this a bug in my code, or in Nickle?  I suspect
> the latter.  (Additionally, why should Nickle need the
> "(cell)" in the initializer?  It seems like it should be
> able to infer this from the lhs type, as does C, but it
> seems to get even more lost without it.)
> 
> Thanks,
> 
> 	Bart
> 
>   /*
>    * Ricochet Robots solver
>    * Bart Massey 2002/8
>    */
> 
>   int size = 16;
> 
>   typedef enum {
>       BLANK, ME, DRONE, TARGET
>   } cellval;
> 
>   typedef struct {
>       cellval val;
>       /* 0 == N, 1 == E, 2 == S, 3 == W */
>       bool[4] wall;
>   } cell;
> 
>   cell[size, size] cells = {
>       {(cell){val = cellval.BLANK,  wall = {false ...}} ...}
>       ...
>   };
> 
> 
> _______________________________________________
> Nickle mailing list
> Nickle@nickle.org
> http://nickle.org/mailman/listinfo/nickle


From nickle@nickle.org  Thu Aug 29 07:30:24 2002
From: nickle@nickle.org (Bart Massey)
Date: Wed, 28 Aug 2002 23:30:24 -0700
Subject: [Nickle]union switch has unreachable default
Message-ID: <E17kIoy-0001Ci-00@bart.cs.pdx.edu>

When I saw "union switch has unreachable default" I was very
impressed: quite cool to check!  Unfortunately, I saw it in
a context like

  typedef enum { V1, V2 } e;
  e v;
  union switch(v) {
   case V1:
       /* handle V1 */
       break;
   case V2:
       /* handle V2 */
       break;
   default:
       abort("somebody expanded the union datatype: fix me");
  }

As cool as it is, I'm afraid it has to go...

	Bart


From nickle@nickle.org  Thu Aug 29 07:38:26 2002
From: nickle@nickle.org (Keith Packard)
Date: Wed, 28 Aug 2002 23:38:26 -0700
Subject: [Nickle]union switch has unreachable default
In-Reply-To: Your message of "Wed, 28 Aug 2002 23:30:24 PDT."
 <E17kIoy-0001Ci-00@bart.cs.pdx.edu>
Message-ID: <E17kIwk-0002Ni-00@localhost>

Around 23 o'clock on Aug 28, Bart Massey wrote:

> As cool as it is, I'm afraid it has to go...

I could add the parallel error if you have a union case which is missing 
some elements.  That way you'd get a compile-time error instead of your 
run-time exception.

-keith




From nickle@nickle.org  Thu Aug 29 07:44:53 2002
From: nickle@nickle.org (Bart Massey)
Date: Wed, 28 Aug 2002 23:44:53 -0700
Subject: [Nickle]union switch has unreachable default
In-Reply-To: Your message of "Wed, 28 Aug 2002 23:38:26 PDT."
 <E17kIwk-0002Ni-00@localhost>
Message-ID: <E17kJ2z-0001Dh-00@bart.cs.pdx.edu>

I've seen this before: ML does it.  Now if you just want to
check a couple of cases, it's a pain.

Although it's better in C/Nickle than ML, actually: you can
just write
  union switch(v) {
  case V1:
    /* handle V1 */
    break;
  default:
    /* only care about V1 */
    break;
  }
to shut the compiler up.  Which would be OK, I guess.

Your call.

	Bart

In message <E17kIwk-0002Ni-00@localhost> you wrote:
> 
> Around 23 o'clock on Aug 28, Bart Massey wrote:
> 
> > As cool as it is, I'm afraid it has to go...
> 
> I could add the parallel error if you have a union case which is missing 
> some elements.  That way you'd get a compile-time error instead of your 
> run-time exception.
> 
> -keith
> 
> 
> 
> _______________________________________________
> Nickle mailing list
> Nickle@nickle.org
> http://nickle.org/mailman/listinfo/nickle


From nickle@nickle.org  Thu Aug 29 16:52:40 2002
From: nickle@nickle.org (Keith Packard)
Date: Thu, 29 Aug 2002 08:52:40 -0700
Subject: [Nickle]Union value semantics
Message-ID: <E17kRb6-0002YK-00@localhost>

Nickle currently treats unions as a mutable object and associated tag.  
This follows the C model of treating unions as structs where the 
offset of all of the elements was zero.  

I'm sure I'll surprise many when I note that unions are currently 
implemented as mutable objects.  In:

	> typedef union { int X; string Y; } U;
	> U x;
	> x.X = 12;
	> x
	X = 12
	> x.Y = "hello";
	> x
	Y = "hello"

Executing 'x.X = 12' performs the following gymnastics:

	1)	Note that x is unset
	2)	Create a union value with tag set to 0 (!), set x to this value
	3)	Fetch the value stored in x
	4)	Note that the value is a union, not a struct
	5)	Set the current union tag to 'X'
	6)	Create a reference to the union storage location
	7)	Store 12 through the reference

I know this looks bizarre; we'd obviously prefer:

	1)	Create a reference to x
	2)	Note that x is of type union
	3)	Create a union value of type 'U' with tag 'X' and value '12'
	4)	Store the union value through the reference.

This way, unions would be immutable objects, and you wouldn't be able to 
reference union fields.  That particular semantic is visible in:

	> poly q = &x.Y;
	> q
	&12
	> x
	Y = 12		(!)

When the reference to 'x.Y' is created, the tag for 'x' is set to 'Y'; the 
assumption is that the reference will shortly be used to store a value.

One way out of this mire is to create a new representation for a reference
to a union; this new representation would include the tag so that when the
referenced value is fetched, the tag would be checked and when the
reference value is stored, the tag would be set.

Alternatively, we could disallow references to union members.  This would
eliminate the semantic problem discovered above. Without union member
references, the sequence:

	> poly v = x;
	> v.Y = "hello";

is a bit more difficult to compile; 'v' might contain a struct type which 
would require a different code sequence than when 'v' contains a union -- 
the struct case assigns a member of the structure while the union case 
casts the value "hello" to the appropriate union value.  There are two 
choices:

	1)	Detect when 'v' happens to contain a union value and
		perform a union cast operation, else a struct member
		assignment.

	2)	Assume that 'v' is a struct type and generate a run-time
		exception when this is not the case.

I'm leaning towards option 2); the '.' operator is a struct member 
reference unless in a known union type context.

-keith




From nickle@nickle.org  Fri Aug 30 09:13:48 2002
From: nickle@nickle.org (Sarah Williams)
Date: Fri, 30 Aug 2002 01:13:48 -0700 (PDT)
Subject: [Nickle]home.keithp.com
Message-ID: <482CR1000003134@emaserver.trafficmagnet.net>

--1244451653.1030695228625.JavaMail.SYSTEM.emaserver2
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit

Hi

I visited home.keithp.com, and noticed that you're not listed on some search engines! I think we can
offer you a service which can help you increase traffic and the number of visitors to your website.

I would like to introduce you to TrafficMagnet.com. We offer a unique technology that will submit your 
website to over 300,000 search engines and directories every month.

You'll be surprised by the low cost, and by how effective this website promotion method can be. 

To find out more about TrafficMagnet and the cost for submitting your website to over 300,000 search 
engines and directories, visit us at:

http://emaserver.trafficmagnet.net/trafficmagnet/www/r?1000003134.482.23.a67zoY93VVK3gm
 

I would love to hear from you. 


Best Regards,

Sarah Williams
Sales and Marketing 
E-mail: Sarah_Williams@trafficmagnet.com
http://www.TrafficMagnet.com

This email was sent to nickle@nickle.org. 
I understand that you may NOT wish to receive information from me by email. 
To be removed from this and other offers, simply go to the link below:
http://emaserver.trafficmagnet.net/trafficmagnet/www/optoutredirect?UC=Lead&UI=10971326
--1244451653.1030695228625.JavaMail.SYSTEM.emaserver2
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 7bit

<HTML>
<HEAD>
<!-- 1.0 --> 
<TITLE></TITLE>
<STYLE TYPE="text/css">
<!--
TD { font-family: verdana, arial, helvetica; font-size: 11px; color: #000000 }
-->
</STYLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<TABLE WIDTH="600" BORDER="0" CELLSPACING="0" CELLPADDING="0">
<TR>
	<TD>Hi<BR>
	<BR>
	I visited <A HREF="http://emaserver.trafficmagnet.net/trafficmagnet/www/r?1000003134.482.5.4zG5RDvoLgsY8J">home.keithp.com</A>, and 
	noticed that you're not listed on some search engines! I think we can offer 
	you a service which can help you increase traffic and the number of visitors 
	to your website.<BR>
	<BR>
	I would like to introduce you to <A HREF="http://emaserver.trafficmagnet.net/trafficmagnet/www/r?1000003134.482.2.q8RQ3Gi5tgaCMg">TrafficMagnet.com</A>. We offer a unique technology 
	that will submit your website to over 300,000 search engines and directories 
	every month.<BR>
	<BR> 
	<TABLE WIDTH="398" BORDER="0" CELLSPACING="0" CELLPADDING="0" ALIGN="center">
	<TR>
		<TD><A HREF="http://emaserver.trafficmagnet.net/trafficmagnet/www/r?1000003134.482.8.pVvP$tnSlrA30R"><IMG SRC="http://www.trafficmagnet.com/img/img_tm.gif" WIDTH="137" HEIGHT="136" BORDER="0"></A>&nbsp;</TD>
		<TD><A HREF="http://emaserver.trafficmagnet.net/trafficmagnet/www/r?1000003134.482.11.xCFZUCCE$9lmVX"><IMG SRC="http://www.trafficmagnet.com/img/img_website.gif" WIDTH="197" HEIGHT="141" BORDER="1"></A></TD>
		<TD VALIGN="bottom"><A HREF="http://emaserver.trafficmagnet.net/trafficmagnet/www/r?1000003134.482.14.+FUm9ddSzx9I6v"><IMG SRC="http://www.trafficmagnet.com/img/img_signup.gif" WIDTH="62" HEIGHT="136" BORDER="0"></A></TD>
	</TR>
	</TABLE>
	<BR>
	You'll be surprised by the low cost, and by how effective this website promotion 
	method can be. <BR>
	<BR>
	To find out more about TrafficMagnet and the cost for submitting your website 
	to over 300,000 search engines and directories, visit <A HREF="http://emaserver.trafficmagnet.net/trafficmagnet/www/r?1000003134.482.17.Ug1zHc$xKwduUn">www.TrafficMagnet.com</A>. 
	<BR>
	<BR>
	I would love to hear from you. <BR>
	<BR><BR>
	Best Regards,<BR><BR>
	Sarah Williams<BR>
	Sales and Marketing<BR>
	E-mail: Sarah_Williams@trafficmagnet.com<BR>
	<A HREF="http://emaserver.trafficmagnet.net/trafficmagnet/www/r?1000003134.482.20.FivITdHsXEEgpB">http://www.TrafficMagnet.com</A> 
	<P>&nbsp;</P></TD>
</TR>
<TR>
	<TD><FONT COLOR="#999999">This email was sent to nickle@nickle.org.<BR>
	I understand that you may NOT wish to receive information from me by email.<BR>
	To be removed from this and other offers, simply <A HREF="http://emaserver.trafficmagnet.net/trafficmagnet/www/optoutredirect?UC=Lead&UI=10971326">click here</A>.<BR></FONT>
	</TD>
</TR>
</TABLE>
<IMG SRC="http://emaserver.trafficmagnet.net/trafficmagnet/www/picture.jsp?UC=Lead&UI=10971326&CRID=482CR1000003134" ALT="." HEIGHT=1 WIDTH=1>
</BODY>
</HTML>
--1244451653.1030695228625.JavaMail.SYSTEM.emaserver2--



