Replies: 4 comments 5 replies
-
This is precisely the purpose of Naumachia. I've thought about consuming the Aiken code inside of a macro. That's one option. My current plan is just to consume the Aiken source code file as part of the Rust compilation, so essentially the same thing. Would be interested in hearing your opinion on that.
Initially this is the plan, just to bootstrap off of Another benefit is that we can generate Rust types from the Aiken code for things like Datum and Redeemer. If you're interested in helping out, I'm looking for more contributors/critics. |
Beta Was this translation helpful? Give feedback.
-
If aiken were to live only as a rust macro we would never get good error messages, formatting, and autocomplete. Cardano deserves a full blown language for smart contracts. Plutus-Tx isn't necessarily a loved experience and I do not wish to follow in their foot steps. The idea is to expose aiken Project building as a crate in addition to the main CLI. Now that being said, it would be neat to have a macro for writing inline Untyped Plutus Core. |
Beta Was this translation helpful? Give feedback.
-
I think this particular argument should not be overlooked:
From my past experience, trying to blur the separation line between two domains that have vastly different constraints never works quite well. The prime example being JavaScript / Node.js. In general, backend code ends up having completely different needs and constraints than the frontend code, and they also end up being developed by different teams. Having a clearer frontier with clear declared interfaces make it a lot easier to deal with a system at scale. Plus, when embedding a language into another, there are many assumptions that one can't make anymore regarding the embedded language. It becomes harder to write specialized tools and optimizations specifically for that domain. We observe this with Plutus-Tx which is NOT Haskell. Very little from the Haskell ecosystem can be reused in Plutus-Tx; the framework had to redefine a set of standard libraries, and the execution VM has very different assumptions than GHC's runtime. Plus, there are features of the languages which aren't available like higher-kinded types, ad-hoc polymorphism or even just, pattern-matching on some types (such as integer). Thus in practice, we treat on-chain Haskell and off-chain Haskell as two different languages and separate the code -- with a not so clear separation line unfortunately. More, because of: (a) the type-system in (real) Haskell is more expressive than the subset we've access to in Plutus-Tx and; We are forced to cut some corners in the modelling of on-chain types which often ends up being simply ByteString and list of ByteStrings without much more effort put in the representation of complex data-types. Hence why, I strongly believe that there needs to be a dedicated, separate, language where the assumptions that the compiler and tools make can be specifically stated in the context for which the language was designed: on-chain execution. On top of that, it should be possible to define bridges, code generators, macros etc.. to help interoperability with other languages but -- I wouldn't make it a "killer argument" for not writing a dedicated language. |
Beta Was this translation helpful? Give feedback.
-
One other example that might be interesting to look at is SQL. While SQL can be written in separate files, it can also be embedded in other languages. I would argue that the way SQL is used to access a database is similar to how smart contracts are used to access a blockchain. There are two main ways to embed SQL in another language: as a string or through a language-native API (for example jOOQ or Exposed). The latter approach seems to be similar to what plu-ts is doing. When SQL is embedded as an API the IDE integration already works out of the box and for the string case there are IDEs out there with good integration: syntax highlighting, auto-complete, and so on. One major advantage of embedded SQL is that you can easily parameterize/customize the script depending on data from your main application. In theory you could also check the correctness and whether the types of the script match the types of the application at compile time but many frameworks don't do that. I wonder how parameterization will work for Aiken when code is written in separate files. There is also the risk of SQL injection attacks which Aiken would need to handle as well, if there was some way to embed Aiken as a string into another language. For SQL, from what I have seen so far, people tend to use embedded scripts when scripts are small and when there are many scripts and separate files for bigger scripts. Generally I agree with the arguments so far for keeping Aiken a separate language but I still think that having an additional way to embed Aiken (maybe for small or heavily parameterized scripts) might make sense in the future. Maybe as a separate project that builds on top of the API that Aiken exposes. |
Beta Was this translation helpful? Give feedback.
-
I wonder whether you have considered building the Aiken language as a procedural Rust macro instead of a separate language. This would allow Aiken code to be embedded into Rust similar to how Plutus Tx is embedded into Haskell. This is also how Scrypto works.
Here are some pros and cons I could see from a macro-based approach:
I would be interested in your thoughts, whether there are other pros and cons, and whether it would make sense to maybe offer a procedural macro alongside the separate language down the line.
Beta Was this translation helpful? Give feedback.
All reactions