Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 24, 2025

Extends the define-let-to-double-define refactoring rule to handle multiple bindings in let expressions and renames it to define-let-to-multi-define to better reflect its new capability.

Problem

Previously, the rule could only refactor let expressions with a single binding:

(define a
  (let ([b 1])
    (+ b 10)))

would become:

(define b 1)
(define a (+ b 10))

However, it couldn't handle multiple bindings like this:

(define a
  (let ([b 1] [c 2])
    (+ b c 10)))

This is a valuable refactoring pattern that appears in real-world Racket code, such as in DrRacket.

Solution

The rule now accepts multiple bindings and generates the corresponding multiple define statements:

(define b 1)
(define c 2)
(define a (+ b c 10))

Safety checks ensure the refactoring only applies when:

  • None of the new bindings would shadow existing identifiers in the context
  • Later bindings don't depend on earlier ones (preventing invalid let* semantics)
  • Free identifiers in the surrounding context aren't affected

Changes

  • Extended pattern matching to accept [nested-id:id nested-expr:expr] ...+ instead of single binding
  • Added check to prevent introducing bindings that conflict with existing identifiers
  • Added check to ensure bindings are independent (no sequential dependencies)
  • Renamed rule from define-let-to-double-define to define-let-to-multi-define
  • Updated description to reflect that multiple defines may be produced
  • Added comprehensive test suite covering single bindings, multiple bindings, and edge cases

All existing tests pass, confirming backward compatibility with single-binding cases.

Fixes #623

Original prompt

This section details on the original issue you should resolve

<issue_title>Handle multiple variables in define-let-to-double-define</issue_title>
<issue_description>The define-let-to-double-define rule can rewrite this:

(define a
  (let ([b 1])
    (+ b 10)))

to this:

(define b 1)
(define a (+ b 10))

But it can't rewrite this:

(define a
  (let ([b 1] [c 2])
    (+ b c 10)))

to this:

(define b 1)
(define c 2)
(define a (+ a b 10))

But that's a valuable refactoring to do, as seen here. The rule should also be renamed to define-let-to-multi-define since this could produce several definitions.</issue_description>

Comments on the Issue (you are @copilot in this section)

Fixes #627


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Handle multiple variables in define-let-to-multi-define Handle multiple variables in define-let-to-multi-define Oct 24, 2025
Copilot AI requested a review from jackfirth October 24, 2025 02:51
Copilot finished work on behalf of jackfirth October 24, 2025 02:51
@jackfirth
Copy link
Owner

Closing this in favor of fixing #641 first.

@jackfirth jackfirth closed this Oct 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Handle multiple variables in define-let-to-double-define

2 participants