Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Project is currently unusable.. #66

Open
GordonBGood opened this issue Nov 23, 2024 · 0 comments
Open

Project is currently unusable.. #66

GordonBGood opened this issue Nov 23, 2024 · 0 comments

Comments

@GordonBGood
Copy link

This project seems to have gone stale for almost four years (last PR change on Feb 26, 2021) even though the PureScript documentation where I found a reference to it doesn't refer to it as such...

The project is currently unusable for a multitude of reasons, some of which are as follows:

  1. When a more modern PureScript tool chain has been globally installed to use current versions of PureScript (currently purs version 0.15.15 and spago version 0.93.41), but make file processing still calls these globally and the newer versions are incompatible with the assumptions made in this project; for instance, the new version of spago has different commands and options and the new version of purs doesn't produce exactly the same form of "corefn.json" file (some extra meta tags seem to have been added).
  2. Modern versions of clang (I am currently using clang version 19.1.0) error out when there are duplicate in the various source files, which need to be unified by a common declaration assumption.
  3. The Garbage Collector add-on doesn't currently compile due to incompatibilities with modern versions of the build tools.

These problems can easily be rectified as follows:

  1. The declaration of the "Makefile" macro variables for SPAGO needs to be changed from "spago" to "npm exec -- spago" and the declaration for PURS needs to be changed from "purs" to "npm exec -- purs" in order to refer to the locally installed versions instead of the globally installed versions.
  2. The invocations of the clang compiler needs to have the -fcommon added to its command line options (at least for the compiling from C phases) in order to "commonify" the duplication declarations.
  3. I didn't investigate the problems compiling and/or using the Garbage Collector as I am not interested in its use.

However, in order to be usable for any kind of production project, the project needs A LOT OF WORK, as follows:

  1. The reason I was interested in it was to see if it made any improvements on the performance of PureScript-compiled-to-JavaScript, which is very slow when compared to alternate functional JavaScript "transpiler" languages such as Fable/F# or Elm; for instance, the best I could do for a benchmark that modifies the contents of an array was about ten times slower in PureScript to JavaScript compared to Fable to JavaScript (although PureScript, as a pure functional language, needs to use the ST monad to do such mutations whereas Fable/F# allows direct array content mutation and also has the optimization of using TypedArray's when the contents are numbers, and it being impossible in Elm due to it only having persistent data structures). Of course, the reasons that PureScript is particularly slow are well known as in not doing hardly any optimizations to the generated JavaScript as in using composition chains of functions of one argument when there are multiple arguments and the incessant boxing and unboxing when using monadic forms of code, made even worse when one has to use the MonadRec monad to do stack-safe recursive calls from within nested bind's.
  2. This project doesn't solve any of this other than perhaps the composition chaining of functions with one argument.
  3. This project makes things even worse in basically emulating JavaScript's dynamic typing with tags for every variable also including reference counts for non-primitive variables (even more boxing and unboxing). While it is good that the project opens the use of reference counted memory management, it doesn't do it in a "smart" way and just blindly adds reference counts when a variable is passed to any function and every function releases a reference count for every scoped variable before it returns other than for variables that are returned (an even then it might just add a reference count back again).
  4. The memory allocator typically used by default by C compilers such as clang are typically not optimized for many frequent allocations and deallocations of small heap objects and is usually several times slower than the allocator's used by modern JavaScript engine's such as Google Chrome's V8 JavaScript engine.
  5. The end result is that the little array contents modification benchmark runs about eighteen times slower when compiled with this project to native code than when run output to JavaScript, which is already about ten times slower than the benchmark written in Fable/F# or in JavaScript directly.
  6. Due to the way the project is structured in generating a huge number of libraries for each of the library modules which is a dependency, the compilation time is minutes even for such a little benchmark due to the huge chain of dependencies.

Perhaps the above are the reasons this project has gone stale; while it is possible to fix these problems, it would require an almost complete re-write, as per the following (starting at the bottom):
6. In order to reduce the make time, the output needs to be structured to generate just one C header and code file containing all of the "include's" required so that the compiler can make many less passes, and where the use of these "include's" is unified for multiple uses from different sub-modules.
5. Some of the time related problems are related to mimicking what the PureScript compiler does as to code generation; this needs to be changed to better suit output to a non-dynamic language as for C.
4. The deficiencies in the C memory allocation will be mostly not important if the following recommendations are followed, but a more efficient memory allocator could be investigated.
3. As stated, the generated could should not try to emulated a dynamic typed language system. In order to give reasonable performance, the output optimizer should be "smart" about eliding away reference counts when they cancel each other, and re-using memory allocations of objects when there is a known "last used" for a given object type in the same block of code as a new block is allocated. One could also investigate automatically mutating in place when the last reference to an object is "last used" (for instance, for record modifications, array updates, etc.).
2. If it doesn't already, the project needs to solve the problem of using only functions of one argument when calling functions of multiple arguments with the full set of arguments, since returning function pointers is somewhat awkward in C and made even worse when one has to emulate "closures" (functions capturing free variables from the outer scopes).
2.1. For the best in performance, the project needs to overcome the PureScript-to-JavaScript compiler's limitations in how stack-safe monadic recursion is implemented using even more boxing/unboxing; the usual way for performant functional languages is to pay more attention to inlining of functions/expression and "lifting" of boxing/unboxing to outside the recursive loop.

As stated, this project may have gone stale due to the huge number of performance problems to make it production worthy, which is readily understood considering that even the regular PureScript doesn't rate highly on the most popular languages index...

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

No branches or pull requests

1 participant