Skip to content

Add Describable interface for human-readable source descriptions#39

Draft
robertvansteen wants to merge 4 commits into0.xfrom
claude/add-describable-interface-Jpo2I
Draft

Add Describable interface for human-readable source descriptions#39
robertvansteen wants to merge 4 commits into0.xfrom
claude/add-describable-interface-Jpo2I

Conversation

@robertvansteen
Copy link
Copy Markdown
Contributor

Description

This PR introduces a new Describable interface that enables source objects to provide human-readable descriptions of themselves. This is useful for textualizing the source tree for AI consumption and debugging purposes.

The implementation adds the describe() method to all expression and source classes, allowing them to recursively describe their structure in a readable format.

Type of Change

  • New feature (non-breaking change which adds functionality)
  • Code refactoring

Changes Made

  • Created new Describable interface in src/Describable.php with a describe(): string method
  • Implemented Describable in StaticSource to describe literal values (e.g., "static value 'hello'")
  • Implemented Describable in SymbolSource to describe symbol references with optional namespaces (e.g., "symbol 'math.pi'")
  • Implemented Describable in TypeDefinition to describe typed sources (e.g., "number(symbol 'price')")
  • Implemented Describable in InfixExpression to describe binary operations (e.g., "(static value 1 + static value 2)")
  • Implemented Describable in UnaryExpression to describe unary operations (e.g., "(!symbol 'active')")
  • Added comprehensive test suite (DescribableTest) with 14 test cases covering all source types and nested expressions
  • Added fallback behavior for non-Describable sources using reflection to get class names

Testing

  • Added new tests for the changes (14 comprehensive test cases in DescribableTest.php)
  • Tests cover all source types: StaticSource, SymbolSource, TypeDefinition, InfixExpression, UnaryExpression
  • Tests verify nested and complex expressions work correctly
  • Tests verify fallback behavior for non-Describable sources

Code Quality Checklist

  • My code follows the project's coding standards
  • I have added PHPDoc comments for the interface
  • My changes generate no new warnings or errors
  • I have added tests that prove my feature works

Breaking Changes

N/A - This is a new feature that doesn't affect existing functionality.

Additional Notes

The implementation uses reflection as a fallback for sources that don't implement Describable, ensuring graceful degradation when working with custom source implementations. The StaticSource class uses SebastianBergmann\Exporter for consistent value formatting.

https://claude.ai/code/session_011wv1MvWN6N2u8bYZZz8QA8

Introduces a new optional Describable interface with a describe(): string
method that produces human-readable descriptions of Source trees. All five
core Sources implement it: StaticSource, SymbolSource, TypeDefinition,
InfixExpression, and UnaryExpression. Composite sources recursively
describe their children, falling back to the class short name for
non-Describable sources.

https://claude.ai/code/session_011wv1MvWN6N2u8bYZZz8QA8
- Replace preg_replace with str_ends_with/substr in TypeDefinition to
  avoid PHPStan error from preg_replace's nullable return type
- Add UsesClass attributes for Type classes used in DescribableTest
- Add tests for non-Describable fallback branches in TypeDefinition,
  InfixExpression (both left and right), and UnaryExpression

https://claude.ai/code/session_011wv1MvWN6N2u8bYZZz8QA8
Rework all Describable implementations to produce human-readable natural
language descriptions instead of terse structured notation:

- StaticSource: "the value 42"
- SymbolSource: "the symbol 'price'"
- TypeDefinition: "the symbol 'price' as a number"
- InfixExpression: "the value 1 plus the value 2" with operator word
  mappings and parenthetical grouping for nested expressions
- UnaryExpression: "the negation of the symbol 'active'"

https://claude.ai/code/session_011wv1MvWN6N2u8bYZZz8QA8
Use raw values and operator symbols instead of verbose natural language:
- StaticSource: 42, 'hello', null
- SymbolSource: price, math.pi
- TypeDefinition: price (as number)
- InfixExpression: price * quantity, with parens for nesting
- UnaryExpression: !active, -5

Complex example: price (as number) * (1 - rates.discount (as number))

https://claude.ai/code/session_011wv1MvWN6N2u8bYZZz8QA8
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.

2 participants