Last updated 4 months ago
Cardano on-chain languages are either suboptimal (Plutus) or are too low-level (Aiken, Plutarch). We need a fully-featured functional language with good performance and script binary size.
Create a PureScript compiler backend for UPLC. PureScript has a strict runtime and almost all Haskell features. Some of the tooling can be reused.
This is the total amount allocated to MLabs - Purus: PureScript to Plutus Core compiler. 3 out of 6 milestones are completed.
1/6
Research
Cost: ₳ 75,000
Delivery: Month 2 - Dec 2023
2/6
Proof of Concept
Cost: ₳ 111,557
Delivery: Month 3 - Jan 2024
3/6
A pipeline converting PureScript code to a working validator
Cost: ₳ 86,766
Delivery: Month 4 - Feb 2024
4/6
API development
Cost: ₳ 123,952
Delivery: Month 6 - Apr 2024
5/6
Testing and documenting
Cost: ₳ 92,964
Delivery: Month 7 - May 2024
6/6
Providing Developer Experience
Cost: ₳ 129,522
Delivery: Month 8 - Jun 2024
Drazen Popovic
Sean Hunter
Chase Maity
Vladimir Kalnitsky
Tomasz Maciosowski
No dependencies.
Project will be fully open source.
Problem
Cardano smart contract development is far more painful than it needs to be. Our team has the utmost respect for the existing Cardano contract languages (PlutusTx/Plutarch/Aiken), which are impressive technical achievements. Nevertheless, our practical experience using these languages has shown that technical sophistication alone does not amount to an adequate solution to problems faced by developers working in the trenches of real-world development.
Some of the problems we have encountered with existing solutions are:
Why not PlutusTx?
PlutusTx employs the TemplateHaskell language extension to enable users to write vanilla Haskell code that compiles down to UPLC. On paper, this appears to be an excellent solution. The Haskell development ecosystem contains excellent tooling (mature build systems, a reliable language server that integrates with every mainstream editor/IDE, etc). Moreover, GHC is capable of performing remarkable optimizations when compiling Haskell programs, which presumably could be leveraged to generate efficient and compact UPLC.
Unfortunately, PlutusTx falls woefully short in practice. Most importantly, the UPLC emitted by PlutusTx is, in almost every case we are familiar with, significantly inefficient in terms of both script size and execution speed. While PlutusTx may be suitable for extremely simple scripts, we do not consider it to be a viable option for complex projects. Choosing PlutusTx for a complex project is just too risky - it may turn out that the design for a complex smart contract cannot possibly be implemented in PlutusTx without exceeding script size limits. Even if the script size can be minimized, execution performance is often so poor with PlutusTx that the resulting fees render a contract's protocol economically unviable. These are not merely theoretical objections; several members of our team have been involved in PlutusTx projects which ultimately required complete rewrites in Plutarch - at great expense to clients. We note that some of these projects ultimately failed due to the increased expense of a ground-up rewrite.
It may be possible to squeeze performance gains out of PlutusTx by performing certain optimizations in the Haskell code that serves as input to its `compile` functions. However, this is extremely unintuitive - a developer attempting to optimize PlutusTx is put in the incredibly awkward position where they must reason about how changes to Haskell code affect UPLC output in spite of the fact that Haskell (a lazy language) and UPLC (a strict language) have different semantics. Even if one could account for the different semantics, the machinery that performs the Haskell -> UPLC translation is an incredibly obscure TemplateHaskell. It is unreasonable to expect that even the most talented developers would be able to perform these tasks.
On a more mundane level, PlutusTx simply does not integrate well with the Haskell ecosystem's tooling. We have lost dozens - if not hundreds - of hours tracking down incredibly obscure errors emitted by the Haskell language server when using PlutusTx. Moreover, PlutusTx requires the use of a special standard library, which makes integration with existing Haskell libraries impossible and (again) gives rise to extremely confusing errors if one accidentally mixes functions from the Plutus standard library with functions from Haskell's prelude. These errors are not intractable, but solving them requires a large amount of folk-wisdom that makes it very difficult to onboard new developers and greatly increases development costs.
Why not Plutarch?
Plutarch eschews compilation-via-metaprogramming for a sophisticated embedding strategy that enables an embedded UPLC DSL. In many respects, Plutarch is a substantial improvement over Plutus: Plutarch, when used by an experienced developer, results in scripts with vastly smaller sizes and greatly improved performance compared to an equivalent PlutusTx implementation.
Although these improvements over PlutusTx have enabled more sophisticated smart contracts, the embedding strategy that powers these performance increases entails a severe cost in terms of ergonomics. At a glance, writing Plutarch requires:
As type system enthusiasts, we find Plutarch to be a fascinating example of what is possible when the Haskell type system is pushed to its limits. As smart contract developers, however, our familiarity with Plutarch has made clear that it is not a viable general solution to the problem of Cardano smart contract development. The degree of niche expertise required to make full use of Plutarch is just too high.
Why not Aiken?
Aiken, a bespoke language for developing Cardano smart-contracts with a rust-like syntax, is an excellent solution for developers that do not specialize in functional programming. However, Aiken's main strength - a much simpler type system than Haskell’s combined with conventional imperative syntax - is, at the same time, a limitation: While Aiken's simplicity enables imperative developers to build on Cardano without struggling to adopt a new paradigm, it also prevents functional programmers from leveraging a strong type system to create abstractions and express sophisticated invariants at the type level. Aiken does not support type classes, data-generic programming, effects systems (monads, monad transformers, etc), or optics (functional-style data manipulation). Admittedly, these language features can be difficult to master, but when mastered they provide developers with the power to significantly simplify codebases and write intrinsically secure code. In the context of smart-contract development, the absence of these features is likely to lead to verbose code (which increases auditing costs and increases the potential for bugs) that is less secure (because certain important invariants cannot be expressed without these features).
Nevertheless, we acknowledge that Aiken is the right choice for many projects, especially those with relatively simple on-chain logic. In our experience, many projects have relatively simple on-chain logic, and would do better to choose Aiken than PureUPLC. As functional programmers, however, we believe that the advanced features found in strongly-typed pure functional languages are sometimes the best tool for the job. Aiken, in our view, is one part of the solution to the problem of Cardano smart-contract development - but that it is only one part of the solution.
Solution
We propose to build a UPLC backend for PureScript - a production-ready language that has a mature ecosystem and integrates well with existing Cardano development tools (as have been proven by cardano-transaction-library, also funded by Catalyst in the past). PureScript, in our view, is uniquely well-suited for this task: It is a strict functional language with a strong (but not overcomplicated) type system, was designed from the outset to support multiple backends, and yield an abstract-syntax tree which is particularly suitable for conversion to UPLC.
In order to solve the plethora of problems with existing solutions, we propose to develop a UPLC compiler backend for the PureScript Language. We believe that this is the best solution to the problem of smart contract development on Cardano because:
Our solution is conceptually simple: We will implement a PureScript backend that transforms the PureScript compiler IR (internal representation) into UPLC, and spend the remainder of our budget implementing as many optimizations as possible. (See the sections below for a more detailed discussion of particular challenges and our strategy for overcoming them.)
Risks involved
Market
The proposed solution can be useful for Cardano dApp developers who already have experience with Plutus or just functional programming in general.
Intended Challenge: OSDE: Open Source Dev Ecosystem
Challenge statement: “Can we build a community-owned Open-Source Ecosystem that’s commercially viable to drive growth, increase opportunities, and increase project visibility?”
What does this proposal entail?
At a bare minimum, this proposal entails designing and implementing a UPLC backend for the PureScript compiler that developers can immediately use to quickly build efficient and secure smart-contracts. In order to achieve this goal, we may also have to design and implement PureScript utility libraries for contract development.
Concretely, the problems that we must solve to achieve are stated goals are:
The criterion for success of this project is delivery of a UPLC backend for the PureScript compiler that integrates with existing PureScript tooling, and that developers can immediately use to quickly and ergonomically develop Cardano smart-contracts.
Success can be measured by the number of projects using the tool.
MLabs maintains social presence on Twitter and in Plutonomicon Discord, where updates could be posted. Additionally, the release could be announced on IOG technical Discord. All source code will be available on Github.
MLabs has proven itself as a company employing dozens of Haskell and PureScript software developers and delivering a number of Catalyst-funded projects in the past.
The main goals are:
Feasibility of our approaches to achieve these goals will be evaluated by project managers and technical leadership of the project.
1370 hours * $95/h = 130150 USD
130150 / 0.21 = 619761 ADA
**In the interest of full transparency, please note we have applied a conservative USD/ADA exchange rate in pricing this proposal. This is to ensure our operations remain stable regardless of market conditions. Although we firmly believe the future of Cardano is bright, we recognize the price of ADA and all cryptocurrencies is inherently volatile. Our financial obligations are denominated in fiat. Most importantly, this includes the salary of our engineers whose hard work makes projects like this possible.
In the unlikely scenario of severe negative price movement beyond our forecasted rate, it is possible that MLabs may need to temporarily suspend work on this proposal until the market recovers. Rest assured, this decision would be made solely to protect our business's long-term viability and never taken lightly.
We appreciate your understanding and support, and we are excited to see what we can achieve together.
How does this help developers?
This project will allow developers to use our Purus PureScript backend to generate efficient UPLC code from vanilla PureScript, which we believe will greatly reduce development costs and improve the overall Cardano smart contract development experience.
NB: Monthly reporting was deprecated from January 2024 and replaced fully by the Milestones Program framework. Learn more here
MLabs
MLabs has quickly become one of the premier development firms in the Cardano Ecosystem. We are an IOG Plutus Partner and work regularly with IOG to develop the Cardano blockchain and ecosystem. Our team is composed of talented developers who have helped build community projects such as:
Through our work with early-stage projects, we have one of the largest groups of Haskell/Plutus developers in the community.
Core Team
Drazen Popovic
Chase Maity
Chase is a polyglot software developer with expertise in Haskell and C. He’s interested in type systems, programming language design and performance optimizing compilers. At MLabs, he has worked on both on-chain Plutarch code and off-chain infrastructure; as well as providing technical specialist assistance on Plutus Core and its intricacies. Outside of MLabs, Chase spends time contributing to open source, and learning more about Haskell and type systems.
Sean Hunter
Sean is an engineer with extensive Cardano smart-contract development experience. He has implemented and audited multiple complex projects written in both PlutusTx and Plutarch. Sean's functional programming journey began as an offshoot of his academic interest in formal logic, and to this day he maintains a strong interest in type theory (with a special interest in row types and their applications).
Vladimir Kalnitsky
Vladimir is a software developer with a number of contributions to the PureScript ecosystem and solid experience with Haskell. During his undergraduate years, Vladimir focused on functional programming and type theory. Vladimir is more of a 'hacker' than a scientist, but he still values formal reasoning about code and well-founded software development practices.
Tomasz Maciosowski
Tomasz, a Haskell/Plutus developer, has gained experience through involvement in projects such as Clarity and Charli3. Additionally, he has made contributions to different infrastructure projects like ogmios-datum-cache and cardano-transaction-lib