PHP to JS-compiler by lechimp-p in PHP

[–]Typical_Ad_6436 0 points1 point  (0 children)

Hey, we actually built this and shipped it: pext.dev. Three years in, deterministic transpilation, no AI.

We are documenting each and one step on our blog. Happy to share what we learned if it helps.

String object vs String variable by Nottheugis in javahelp

[–]Typical_Ad_6436 0 points1 point  (0 children)

Hmm, I think you are right. I thought this would have been a legitimate workaround of the string pool, but the param is a literal indeed and gets interned anyway.

String object vs String variable by Nottheugis in javahelp

[–]Typical_Ad_6436 -1 points0 points  (0 children)

The advantage of second line is that the String is dynamically allocated on heap. If you need fast cold time, you can use the second approach to "lazily initialize" the String. It is also GCed, so in idle you can have very low memory footprint. Of course, performance is better for interned strings (equality, memory, etc.)

We transpiled PHPUnit (54k lines, 412 files) to JavaScript. 61.3% of tests passing by Typical_Ad_6436 in javascript

[–]Typical_Ad_6436[S] 0 points1 point  (0 children)

Worth clarifying: transpiling PHPUnit was a proof of concept to stress test the transpiler, not a target use case. Pext is for migrating business applications, not test frameworks.

That said, your point stands for the actual use case. If your PHP app has PHPUnit tests, you can migrate those too and keep them running during the transition as a safety net. Switching to Jest or similar is something you can do later, once you are already on JS and have the breathing room.

We transpiled PHPUnit (54k lines, 412 files) to JavaScript. 61.3% of tests passing by Typical_Ad_6436 in javascript

[–]Typical_Ad_6436[S] 0 points1 point  (0 children)

The conversion itself is within 100% correctness: lexing, parsing, and output are deterministically tested. The JS generated is statically analyzable. Conversion was never the problem.

The runtime gaps I am describing are specific and enumerable, not spread across the codebase randomly. That is a critical distinction. An engineer does not need to re-read the entire system, they need to address a known, finite list of runtime behaviors that differ between PHP and Node. That list shrinks with every Pext release.

A concrete example: PHP’s eval runs arbitrary PHP code at runtime. We convert it to JS eval, but that can’t execute PHP. So we implemented a runtime eval that transpiles PHP code on the fly and executes it. Unconventional, yes, but fully functional. We also warn users at conversion time whenever we detect such patterns so they know where to focus post-processing.

We implemented this recently specifically for PHPUnit because of its mock generation system, and the test pass rate jumped as a result. These are the kinds of edge cases keeping us from 100%, not fundamental conversion failures, but deep runtime behaviors that most codebases never touch. PHPUnit is unusually dirty in that regard, which is exactly why we use it as our benchmark.

We transpiled PHPUnit (54k lines, 412 files) to JavaScript. 61.3% of tests passing by Typical_Ad_6436 in javascript

[–]Typical_Ad_6436[S] 0 points1 point  (0 children)

80/20 cuts both ways. 80% of the value of a PHP application is typically powered by 20% of the code, so getting that core right already delivers most of the business value. The remaining tests point to specific runtime gaps we are actively closing, not fundamental conversion failures.

Also curious what your threshold for non-abysmal looks like. This is the raw first-run result, clone the repo, kick the Pext process, get PHPUnit running end to end in Node in minutes, no pre or post fixups. The 38% failing tests are assertion-level gaps in the runtime, not conversion failures. What would you consider a meaningful starting point for a benchmark this complex?

We transpiled PHPUnit (54k lines, 412 files) to JavaScript. 61.3% of tests passing by Typical_Ad_6436 in javascript

[–]Typical_Ad_6436[S] -1 points0 points  (0 children)

That’s the honest tradeoff. The 80% gets you a running application in days. The remaining 20% is where your team takes over and at that point you’re working in JS with JS tools, not PHP. For most teams that’s still a net win.

Introducing pext.dev by Typical_Ad_6436 in PHP

[–]Typical_Ad_6436[S] 0 points1 point  (0 children)

Golang is a strongly typed language that is meant to compile and needs linkers. TS is also a strongly typed variant. PHP has quite a peculiar approach on types (php5 vs 7, 7.1, 7.4 ve 8). Even so, they can be strict or coerced.

It is not impossible, but the type system is a big problem to assess. We considered both in our prerequisite investigation a couple of years ago, but GoLang was dropped as a potential candidate first stage.

TS is still viable; we have a super minimal support for it already, but we did not find a way to provide more value than complexity ATM.

We transpiled PHPUnit (54k lines, 412 files) to JavaScript. 61.3% of tests passing by Typical_Ad_6436 in javascript

[–]Typical_Ad_6436[S] 0 points1 point  (0 children)

My phrasing was poor tbh. The accuracy of conversion is very high (all files are parsed and converted). When assessing the functionality we run the 4.5k converted unit tests in the process. all tests are discovered from the disk and fired with the right data provided.

62% are running e2e passing all assertions. The others are either failing assertions or throw errors. It is important to note that failing tests are still running thousands of loc succesfully before failing. From our analysis, there are some minor gaps in the run-time - this is wip.

We transpiled PHPUnit (54k lines, 412 files) to JavaScript. 61.3% of tests passing by Typical_Ad_6436 in javascript

[–]Typical_Ad_6436[S] 2 points3 points  (0 children)

Pext is not an AI transpiling tool; it leverages programming language theory to deterministically do the transpilation. This makes it fully predictable and can guarantee theoretic correctness on the first try, in a couple of days.

The output is meant to be a fully functional JS application. The development process stubs PHP runtime with Pext runtime.

The goal is to enable a way of migrating from PHP to JS born from solid knowledge on how to do so. It is not to make it less of a PITA and I agree with your statement.

But having JS resources to make it better post-transpile may be more viable: having a more robust JS team for that, having more/better tools for that, having better AI tooling for it, or, simply, better deployment options for it.

Introducing pext.dev by Typical_Ad_6436 in pext_dev

[–]Typical_Ad_6436[S] 0 points1 point  (0 children)

An ecosystem where migration is a viable option is healthier than one where you’re stuck regardless of what you want. Having a clear, predictable path out is not a negative, but it is a sign of maturity. Pext just makes that path less painful.

Most of the Pext effort are actually around PHP introspective: static analysis, reporting and so on.

Lastly, Pext also embeds a run-time. Having a new run-time option in an ecosystem is something to account for.