Skip to content

[Feature Request] Allow (T) to be treated as T #1476

@NoahStoryM

Description

@NoahStoryM

Is your feature request related to a problem? Please describe.

I noticed that type constructors with zero parameters are sometimes treated inconsistently depending on context.

For example:

> (define-type (Nat) (Natural))
string:1:19: Type Checker: Error in macro expansion -- parse error in type;
 bad syntax in type application: expected a type constructor
  given a type: Nonnegative-Integer
  in: (Natural)
 [,bt for context]
> (define-type (Nat) Natural)
> (ann 123 (Nat))
string:1:9: Type Checker: Error in macro expansion -- parse error in type;
 bad syntax in type application: expected a type constructor
  given a type: Nonnegative-Integer
  in: (Nat)
 [,bt for context]
> (ann 123 Nat)
- : Integer [more precisely: Nonnegative-Integer]
123
> (: add (∀ () (→ Real Real Real)))
> (:print-type add)
(-> Real Real Real)
> (inst add)
string:1:6: Type Checker: Cannot instantiate non-polymorphic type (-> Real Real Real)
  in: add
 [,bt for context]

Similarly, for structures:

> (struct () S ())
> (ann (S) (S))
string:1:9: Type Checker: type cannot be applied
  type: S
  in: (S)
 [,bt for context]
> (ann (S) S)
- : S
#<S>

Typed Racket seems to treat (T) as an invalid type expression when T is a nullary type constructor. This inconsistency causes problems when writing macros that automatically generate type applications.

For example, in a macro like:

(define-record-type (t ...) T
  (make field-tag ...)
  T?
  field-spec ...)

which expands to:

(struct (t ...) struct-spec ...)
(: make (∀ (t ...) (→ t ... (T t ...))))

When (t ...) is (), the result type becomes (T), which triggers a type error — even though semantically it should just be T.

Describe the solution you'd like

I would like (T) to automatically expand to T when T is a nullary type constructor or just a type. This would make Typed Racket more consistent and make it easier to write macros that handle both parametric and non-parametric types uniformly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions