TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Ask HN: A PHP Superset Language

1 pointsby anviusabout 2 months ago
I&#x27;m developing a PHP transpiler and I&#x27;ve created a superset called Simple PHP Superset (SPS). The goal is not to replace PHP but to extend it—making the code easier to read and maintain while preserving full PHP compatibility. Our company’s codebase suffers from numerous issues, and I believe that SPS can help solve these by introducing modern improvements without breaking existing PHP libraries.<p>Here are the most features of SPS:<p>- Full Compatibility with PHP 8:<p>You can mix traditional PHP code (with braces, semicolons, etc.) with SPS syntax. In strict mode, warnings are emitted if you don’t follow the recommended style.<p>- Minimalist, Clean Syntax:<p><pre><code> + Use `end` instead of braces to close blocks. + Instantiate classes by calling them like functions (no need for `new`). + Use `raise(...)` in place of `throw new`. </code></pre> - Private by Default:<p>All members (variables, functions, properties) are private by default. Use the keyword `pub` to expose them publicly.<p>- Immutable by Default:<p><pre><code> + Variables declared with `var` are immutable once assigned, and only variables declared with `mut` can be modified. + Function parameters intended to be modified must be marked as `mut` (transpiling to PHP by-reference). </code></pre> - Strict Static Typing &amp; Union Types:<p>You must declare explicit types (e.g. `int`, `string`) and use union types (e.g. `int|string`) for enhanced compile‑time safety.<p>- Modern Data Structures &amp; Manipulation:<p><pre><code> + Slicing: Extract subarrays using the notation `[start:end]` (similar to Python). + Maps &amp; JSON-like Objects: Use the `{ key: value }` notation to define maps and object literals, which is cleaner than PHP’s `=&gt;`. + Destructuring: Easily extract values from arrays, tuples (using parentheses), and JSON-like objects (using braces). </code></pre> - Named Parameters:<p>Functions can be called with named parameters in any order for improved clarity.<p>- Concurrency with Coroutines:<p>Launch concurrent tasks with `php(expr)`, which executes the expression in a Fiber (PHP 8.1–based). Use a scheduler (e.g. `Scheduler.joinAll()`) to wait for all coroutines to complete.<p>- Enhanced Functional Programming:<p>An unified standard library (`Standard\`) provides higher‑order functions like `map`, `filter`, and `reduce` in camelCase, with a logical parameter order. Also, most of PHP functions implemented with a logical order.<p>- System Types for Resources:<p>It includes classes like `System\File` to wrap system resources (files, sockets, streams) in an object‑oriented manner, providing methods like `read()`, `write()`, and `close()`, with automatic error handling.<p>- Composition with `compose`:<p>Emulating Go’s embedding, use `compose` to inject the behavior of a normal class into another. For example, `compose Logger` in a class will automatically create an internal field and delegate its public methods so you can call `this.log(...)` directly without referencing the internal variable.<p>- Multiple Return Values:<p>Functions can return multiple values via tuples, making it easier to communicate results without resorting to arrays or ad‑hoc structures.<p>I&#x27;ve designed SPS to modernize PHP by providing a cleaner (specially to avoid usual mistakes in our codebase), more expressive syntax along with stricter static typing, immutability by default, named parameters, slicing, JSON‑like maps and objects, and enhanced functional programming features—all while being fully compatible with existing PHP code. Wiping code of `&lt;?php`. It also should introduce concurrency through coroutines based on PHP 8.1 Fibers and allows composition via `compose`, letting you embed complete class behavior directly into another class.<p>I&#x27;m actively developing the transpiler and would love to hear feedback from the community. Does this approach make sense? What aspects should I improve or change? Should I abondon it? Any input would be greatly appreciated!<p>Thank you!

2 comments

psychoslaveabout 2 months ago
Do you have some repository yet?
anviusabout 2 months ago
Here an example code:<p><pre><code> &#x2F;&#x2F; NOTE: $this file is provided as a single file as an example only. &#x2F;&#x2F; Classes should be publicly accessible and not private, but in $this example it&#x27;s not necessary. &#x2F;&#x2F; It is possible add composition of classes go-style with compose. namespace Domain use \StdPS\String use \StdPS\Array use \StdPS\Time use \StdPS\Scheduler class Contact var $id: string var $name: string var $email: string construct($id: string, $name: string, $email: string): void $this.id = $id $this.name = $name $this.email = $email end pub func updateEmail($newEmail: string): void $this.validateEmail($newEmail) $this.email = $newEmail end toString(): string return String.Join([&quot;Contact(id:&quot;, $this.id, &quot;, name:&quot;, $this.name, &quot;, email:&quot;, $this.email, &quot;)&quot;], &quot; &quot;) end func validateEmail($newEmail: string): void if (!String.Email.Validate($newEmail)) raise(InvalidArgumentError, &quot;Invalid email address: &quot; + $newEmail) end end end interface ContactRepository pub func save($contact: Contact): void pub func findById($id: string): Contact|void pub func findAll(): [Contact] end class InMemoryContactRepository: ContactRepository mut $contacts: [string:Contact] construct(): void $this.contacts = [] end pub func save($contact: Contact): void $this.contacts[$contact.id] = $contact end pub func findById($id: string): Contact|void if (isset($this.contacts[$id])) return($this.contacts[$id]) end return(null) end pub func findAll(): [Contact] return($this.contacts) end end pub class ContactService var $repository: ContactRepository construct($repo: ContactRepository): void $this.repository = $repo end pub func registerContact($id: string, $name: string, $email: string): void var $contact = Contact($id, $name, $email) $this.repository.save($contact) end pub func getContactInfo($id: string): string|void var $contact = $this.repository.findById($id) if ($contact) return($contact.toString()) end return(null) end pub func listAllContacts(): [Contact] return($this.repository.findAll()) end end mut $repo = InMemoryContactRepository() var $service = ContactService($repo) $service.registerContact($id=&quot;1&quot;, $name=&quot;Alice&quot;, $email=&quot;alice@example.com&quot;) $service.registerContact($id=&quot;2&quot;, $name=&quot;Bob&quot;, $email=&quot;bob@example.com&quot;) echo(String.Join([&quot;Contact Info:&quot;, $service.getContactInfo(&quot;1&quot;)], &quot;\n&quot;)) echo(&quot;\nAll Contacts:\n&quot;) var $all = $service.listAllContacts() foreach($all, $contact) echo($contact.toString(), &quot;\n&quot;) end var $numbers = [10,20,30,40,50] var $subNumbers = $numbers[1:4] &#x2F;&#x2F; Expecting [20,30,40] echo(&quot;Sliced Numbers: &quot; + String\Join($subNumbers, &quot;, &quot;)) func simulateTask($id: int): void Time\Sleep(1) echo(&quot;Task &quot; + $id + &quot; completed&quot;) end php(simulateTask(1)) php(simulateTask(2)) echo(&quot;Launched tasks concurrently.&quot;) Scheduler.JoinAll()</code></pre>
评论 #43551218 未加载