julia-script / julia-script/silk

type-system: Add tuple types and tuple expressions

Open
#17 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

backend diagnostics enhancement lsp memory new feature P3 parser spec-change syntax type-system
Dominant language
TypeScript
Stars
48
Forks
0
Avg merge
4h 49m
Merged PRs (30d)
213

Description

Context

Silk has exactly 12 type constructors: the builtin scalars, string, the bottom type,
nominal types, type parameters, failure projections, fixed arrays, slices, references,
callables, effects, and structural unions
(packages/compiler/src/Type.ts:179-191). None of them is a tuple. A function that must
return two values therefore needs a named struct, even when the pair has no meaning
outside the one call.

Current behavior

A user declares a struct for one use:

pub struct DivisionResult {
  quotient: u32
  remainder: u32
}

pub fn divide(value: u32, divisor: u32) -> DivisionResult {
  return DivisionResult {
    quotient: u32.divide(value, divisor),
    remainder: u32.remainder(value, divisor)
  }
}

The struct adds a public name, a declaration, and an import for every consumer. The names
quotient and remainder are useful, but the type name is not.

The syntax (u32, u32) does not parse as a type. The parser reads (T) as a
parenthesized type, so a single element in parentheses already has a meaning.

Requirements

  1. The type grammar must accept a tuple type with two or more element types.
  2. The expression grammar must accept a tuple expression with two or more elements.
  3. The parser must keep (T) as a parenthesized type, not a one-element tuple.
  4. The parser must keep (expression) as a grouped expression.
  5. The parser must accept a trailing comma in a tuple type and in a tuple expression.
  6. A tuple element must be reachable by an index, such as pair.0.
  7. A match pattern must accept a tuple pattern that binds each element.
  8. Two tuple types must be the same type when every element type is the same.
  9. The layout must place the elements in declaration order, as a struct does.
  10. A tuple must follow the existing move, borrow, and drop rules of a struct.
  11. The empty tuple () must keep its current meaning as the unit type.

Example

pub fn divide(value: u32, divisor: u32) -> (u32, u32) {
  return (u32.divide(value, divisor), u32.remainder(value, divisor))
}

pub fn showRemainder(value: u32) -> u32 {
  let result = divide(value, 10)
  return result.1
}

Out of scope

  • A one-element tuple. The syntax (T) keeps its current meaning.
  • A named tuple field. A struct covers that case.
  • A tuple with more than a fixed number of elements at runtime.
  • A conversion between a tuple and a struct with the same element types.
  • A generic function over the length of a tuple.

Dependencies

None.

Acceptance criteria

  • The parser accepts (u32, u32) as a type and keeps the syntax tree lossless.
  • The parser accepts (a, b) as an expression.
  • A parser test shows that (T) stays a parenthesized type.
  • A parser test shows that (expression) stays a grouped expression.
  • A parser test shows that a trailing comma is accepted in both positions.
  • A semantic test shows that pair.0 selects the first element with its exact type.
  • A semantic test shows that an index outside the length gets a diagnostic.
  • A test shows that a tuple pattern in a match binds every element.
  • A layout test shows the element offsets in declaration order.
  • openspec/specs/bootstrap-syntax/spec.md gets a new type-grammar requirement.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with packages/compiler/src/Type.ts:179-191 and openspec/specs/bootstrap-syntax/spec.md, then trace the existing parser, struct semantics, matching, and layout handling. Add the parser, semantic, pattern, and layout tests listed in the acceptance criteria. Done means tuples support construction, indexing, matching, type equality, layout, and existing ownership rules without changing one-element or unit syntax.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.