Comments (12)
Even better than using Dhall for contract parameters files, might be to find a way to embed Dhall into our templates directly, because:
- Every contract could effectively become a template, because we'd be able to derive one contract from another (similar to how Jina2 template inheritance works). Using this approach would allow us to avoid having multiple different types of files to represent a single contract (right now we have two distinct types of files: templates and parameters), whereas in this schema you'd only have a chain of inheritance of contract templates.
- Contracts can selectively override components/sections of parent templates.
- Contracts can selectively override parameters defined by parent templates.
- Contracts (and templates) can define functions that could be accessible to child templates.
- Contracts could potentially override functions specified by parent templates.
Finding an elegant way to embed Dhall into plain text could effectively facilitate a pretty powerful general-purpose templating language actually.
from themis-contract.
yeah, this is also what I was thinking. I think we could just use Dhall's string interpolation for the template. It's worth a shot in any case :)
from themis-contract.
Here's an example of templating in pure dhall. With a few little pieces of tooling and little library of dhall functions, I think we could make this quite easy to work with: https://gist.github.com/shonfeder/5c02b8430e86da8c2b1880d2a1589bab
from themis-contract.
I was thinking of an approach that prioritizes the contract text and allows one to embed programming into it (as opposed to trying to embed the contract text into code), like so (using Jinja2 syntax for the templating):
---dhall
{-
The initial Dhall code here defines globally accessible functions/types/values.
It's defined inside a Markdown preamble, which, in theory, could be used for
pretty much any kind of text-based format (e.g. LaTeX), if your preprocessor
strips it out in its first stage.
We could also support other simple markups within the preamble by specifying
their type as the preamble begins (e.g. replacing "---dhall" above with
"---json" or "---toml").
-}
{- We'd probably import this type instead of defining it here. -}
let Company: Type
= {
name: Text,
address: Text
}
let client: Company
= {
name: "Client",
address: "Somewhere"
}
let supplier: Company
= {
name: "Supplier",
address: "Somewhere Else"
}
in {
client,
supplier
}
---
# Service Agreement
This is an agreement between {{client.name}} and {{supplier.name}}.
## Some clauses
1. This
2. Is
3. Always
4. Present
{% block optionalClause %}
## Optional Clause
Some text here that can be overridden in a child template.
{% endblock optionalClause %}
So this "template" would effectively be a contract in its own right. But you could also derive another contract from it:
---dhall
{-
The resulting data from this preamble will be merged with the parent
template's data, with this contract's data taking precedence.
-}
{- Here we'd probably just import a company definition -}
let Company: Type
= {
name: Text,
address: Text
}
let client: Company
= {
name: "Company A",
address: "Somewhere"
}
let supplier: Company
= {
name: "Company B",
address: "Somewhere Else"
}
in {
client,
supplier
}
---
{% extends "/path/to/service/agreement" %}
{% block optionalClause %}
## Optional Clause
This changes the text of the clause. Or you can just leave it out entirely
to have the block removed from the original template.
{% endblock %}
It's automatically clear, just from the template usage above, what parts of the parent template are overridden/replaced without the need to build a template diff system on top of Git.
from themis-contract.
as opposed to trying to embed the contract text into code
Just to be clear, my aim was not to embed the contract into code. That's just an expedient to test my hypothesis that dhall is sufficient for templating on it's own, without need for an additional templating system. Turns out it is! :)
The benefit of the pure dhall templating is that we'd get a single, unified logic for both statically typed templates and sub-Turing complete, well-defined logic for computing values, instead of having to reason about both a templating system and a programmable configuration language.
As I noted in the comments on my gist, we'd want tooling so that user only has to edit the markdown, rather than a markdown string inside of a dhall expression.
I should note, I really just wanted to show the proof of concept, so we know that options is available. I'm not at all sure that this would be a wonderful way forward.
I have no objection to embedding dhall in the template file, I'm not clear on the benefit of that tho. Could you maybe say few words on what this offers?
The template inclusion seems useful for modular contracts, but iiuc that's just a feature of Jinja, so not directly pertinent to this issue about configuring parameters via Dhall. Perhaps we should open another issue for considering alternative templating languages?
It's automatically clear, just from the template usage above, what parts of the parent template are overridden/replaced without the need to build a template diff system on top of Git.
I see this is a demo of what you described in #23 (comment) Seems workable! Your example here inspired some ideas, but I'll post those on #23, so they're on topic.
from themis-contract.
Ah! I see you lay our your reasons for wanting to include configs in the same file as a contract in #25 (comment). Sorry I missed that context before. I also know recall discussion about being able to embed configuration and limited programming logic in the body of templates.
I think using fenced code blocks for this would probably the most natural approach, and then filtering out ones tagged a certain way from the rendered file.
from themis-contract.
I think using fenced code blocks for this would probably the most natural approach, and then filtering out ones tagged a certain way from the rendered file.
I thought of that actually, but have purposefully avoided it because of the following model:
What I'm looking for in a contract templating language is something that operates on plain text, prior to the extraction of the higher-level semantics.
I wanted to reserve the use of the higher-level semantics for application-level concerns, as opposed to plain text operations. For example, fenced code blocks could be used to facilitate smart contracts - but this operates at a more abstract level than template-level concerns.
from themis-contract.
I see! My initial feeling is that i'd just rather keep the configs in a separate file, rather than having to distinct ways of embedding code in the contract for different purposes. But that's just a gut reaction, and this implementation detail isn't of much consequence ime.
In light of your graphic: If we use Dhall as the config format to feed the templating, I guess we end up introducing something which has very high levels of semantic structure, but is "prior" to the templating language in terms of it's place in the process. My proposal to use pure Dhall templating would change the model in a kind of interesting way, since the templating language would then be more structured than the markup language.
from themis-contract.
I see! My initial feeling is that i'd just rather keep the configs in a separate file, rather than having to distinct ways of embedding code in the contract for different purposes. But that's just a gut reaction, and this implementation detail isn't of much consequence ime.
If a single file represents a contract, it's more skeuomorphic to users' current conceptions of contracts than the multi-file approach. This is an important factor that contributes to adoption of any new tech.
In light of your graphic: If we use Dhall as the config format to feed the templating, I guess we end up introducing something which has very high levels of semantic structure, but is "prior" to the templating language in terms of it's place in the process. My proposal to use pure Dhall templating would change the model in a kind of interesting way, since the templating language would then be more structured than the markup language.
You're right, and it's a shortcoming of the model in that it fails to accurately represent levels of semantic structure in the computations that happen at the templating level. Technically the template level for the approach I'm assuming has very little semantic structure:
- The
---dhall
and---
opening and closing tags for the preamble (where the interpretation of the preamble depends on the opening tag structure). - The
{{
and}}
opening and closing tags for variable insertion. - The variations of
{%
and%}
-based tags for more complex operations.
Perhaps a better label for the vertical axis of the graph is something like "processing stage". But it's hopefully evident that the goal of the graph is to emphasize that the semantics for one stage shouldn't be mixed or overlap with that of another stage?
I'll open a separate issue to do with templating in general, because I do think the Dhall conversation here has expanded to encompass contract templates in general 👍
from themis-contract.
Something else I just realized looking at my pure dhall templating example: if you just write the config directly in the let, instead of importing it, you'd effectively get the single file templating you're proposing. Eg.:
let lib = ./lib.dhall
let config =
{ company = "Well Typed Co."
, employee = "Hamza Edge"
, salary = { amount = 100000, period = lib.Period.Monthly }
, startdate = "2020-09-09"
, tasks = [ "Mop the fluzit", "Soak the flange", "Flumix the flounce" ]
}
: ./config.dhall
in ''
---
title: Employment Agreement
---
This agreement is between ${config.company} and ${config.employee}.
# Compensation
${config.company} will pay ${config.employee} CAD ${nat.show config.salary.amount}
on a ${lib.showPeriod config.salary.period} basis.
# Tasks
The employee will be expected to perform the following tasks (among others):
${lib.itemize Text text.show config.tasks}
''
Pretty sure this isn't the optimal solution, but it's worth noting how much we can get for free here :)
from themis-contract.
That looks amazing to me!
The challenge is: will it be the most amazing approach for the average user in our target audience? Is that how they want to compose contracts? I'm not saying it's not: I'm just saying that we need to track this as one option and take it to some users and ask them.
Also, how do you incorporate signatures?
from themis-contract.
Implemented! 🎉
from themis-contract.
Related Issues (20)
- compile needs a sanity check for variables typos, etc. HOT 3
- do comments in the markdown get included as metadata in the rendered PDF ? HOT 2
- error when no upstream set in `contract.dhall` and running `themis-contract upstream diff`
- compile should have option to commit & push
- compile should bind the: signature+underline+name together HOT 2
- explore & document how to best use pandoc for optimizing .docx -> .md conversions
- compile panics when there is error in the mustache templating
- compile: change `dhall-to-json output` verbosity (on error) from DBG to ERR
- signing should insert the current date/time/hash alongside the signature
- Identify logical unit tags from commit messages as well as github issues and pull requests HOT 1
- [TRC-IMPL.2::PREFIX.2] Record tag implementatino relationships HOT 1
- compile will sign if the signature files are present in the directory HOT 2
- create an invoicing template
- `new` command fails when attempting to create Git repo
- Dockerfile
- Get rid of IDs for signatures/signatories and just use e-mail addresses HOT 2
- General project context/history questions HOT 4
- themis-contract new [path/to/template.md] HOT 2
- auto push & auto commit should be off by default HOT 1
- themis-contract compile [--update] flag HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from themis-contract.