Scalar Pseudo-Objects
Tier 0 · Story 03Complete
Tyhp lets you call methods on scalar values (string, int, float, bool, array) using object syntax when you define extension methods. The compiler rewrites $value->method($args) to a static call on the extension class. There is zero runtime overhead — no wrapper objects are created.
Tier 2 · Story 21Planned
Not in this alpha
A built-in catalog of scalar methods (toUpper, contains, len, map, …) is planned for Story 21 (tyhp/php support extensions). It is not included in Tyhp 805.0.0-alpha.1. User-defined extension methods work today. Until the catalog ships, call PHP functions such as \strtoupper($name) or write (and import) your own extensions.
How to Write an Extension
Declare an extension with methods whose first parameter is marked extends Type $this (the receiver). The method body is ordinary Tyhp; $this has the extended type.
<?tyhp
extension StringHelpers {
function toCamelCase(extends string $this): string {
return $this;
}
function trimLower(extends string $this): string {
return \strtolower(\trim($this));
}
}
string $name = 'hello_world';
string $camel = $name->toCamelCase();
Compiles to:
<?php
declare(strict_types=1);
$name = 'hello_world';
$camel = \StringHelpers::toCamelCase($name);
When the extension lives in another file or namespace, import it with use extension:
<?tyhp
use extension App\Extensions\StringHelpers;
string $name = 'hello_world';
string $camel = $name->toCamelCase();
See Use Statements for adaptation syntax (as / hide) on use extension.
Method Chaining (User Extensions)
If your extensions return the extended type (or another type that also has extensions in scope), you can chain calls. Each call is rewritten independently.
<?tyhp
extension StringHelpers {
function trimmed(extends string $this): string {
return \trim($this);
}
function lower(extends string $this): string {
return \strtolower($this);
}
function dashed(extends string $this): string {
return \str_replace(' ', '-', $this);
}
}
string $input = " Hello World ";
$result = $input->trimmed()->lower()->dashed();
<?php
$input = " Hello World ";
$result = \StringHelpers::dashed(\StringHelpers::lower(\StringHelpers::trimmed($input)));
Calling on Literal Values
User extension methods can be called on literals. Wrap integer and float literals in parentheses.
<?tyhp
extension IntHelpers {
function asChar(extends int $this): string {
return \chr($this);
}
}
extension StringHelpers {
function parts(extends string $this, string $sep): array {
return \explode($sep, $this);
}
}
$char = (65)->asChar();
$parts = "a,b,c"->parts(",");
Best Practices
Tip
Write small extension methods that wrap \str_* / \array_* (or your own helpers) when the method-call style helps readability. Import them with use extension in each file that needs them.
Tip
Chain only extensions you defined (or imported). A built-in $name->trim()->tolower() catalog is planned (Story 21) and is not in this alpha — use \strtolower(\trim($name)) or your own wrappers until then.
Tip
Keep the receiver as extends string $this (or extends array $this, …) so call sites read as instance methods while emit stays a static call.
Common Mistakes
Danger
Don't assume PHP string/array functions are already methods on scalars in this alpha. $name->toUpper() and $numbers->map(...) are planned (Story 21). Until that catalog ships, use \strtoupper($name) / \array_map(...) or your own extensions.
Danger
Don't expect actual object instances — these are compile-time rewrites. Calling a method that is not an imported extension produces a compile error.
Danger
Don't import an extension class with a plain use and expect methods to attach. Use use extension to activate extension methods on the target type (same-file extensions are already in scope).
Danger
Don't try to assign scalar methods to variables — $fn = $name->trimmed is not valid. These are method calls, not callable properties.