Record (Union) type declaration syntax

Just out of curiosity, why are not things like records defined as

type TWFS = record { const f, m : uint; var v : [1..f,1..m] real(32); };

rather than the syntax

record TWFS { .... };

I can't speak to the exact reason why, but I know I personally would
find that unnecessarily verbose. The compiler and programmer can
recognize that a class, record, union, or even enum is a type without
having to be explicit about it, so I don't feel the need to be explicit
about it.


I'd say that this is a case of following the lead of languages that we grew up with or were inspired by in designing Chapel.


Just curious.I often type my aforementioned syntax until the compiler corrects me. I always thought Chapel had its roots in Modula which uses my aforementioned syntax. I always put a semi-colon after the trailing brace of a record definition out of habit.

1 Like

Modula definitely had an influence on Chapel syntax, but in this case I think the C/C++/Java family of languages had a bigger impact.

It could certainly be reasonable to file a feature request asking to support the syntax you propose, but I'm hesitant to adopt it for the following reasons: First, even if we were to support it, I don't think we'd ever abandon the current syntax. So one reason not to support it is to avoid having two similar-but-different ways of saying the same thing.

A rationale for our current approach might be that most Chapel declaration statements that are creating a brand-new thing take a keyword saying what is being declared (a variable, a procedure, a type alias, etc.) then the name of the thing being declared, and then its definition, so record R { ... } fits that pattern.

Of course, type t = typeDefinition; also follows the pattern, where the reason your declaration doesn't parse is that we don't have a way of declaring an anonymous record type today, which is what I interpret your record { ... } declaration to be. By anaology, we don't support:

proc foo(r: record { const x: int; var s: string; }) { ... }

And I think this is generally a good thing since an identical record type would presumably need to be entered somewhere else in the program in order to declare variables that could be passed to such a procedure—so keeping those multiple definitions in sync and requiring the compiler (or a programmer) to prove to itself that they're the same type feels a bit unwieldy

And of course, one other complicating factor is that record types often define methods in addition to fields, which quickly makes the notion of an anonymous record type get unwieldy.


I was not proposing a change. Just curious.

1 Like