catalalang / catala Goto Github PK
View Code? Open in Web Editor NEWProgramming language for literate programming law specification
Home Page: https://catala-lang.org
License: Apache License 2.0
Programming language for literate programming law specification
Home Page: https://catala-lang.org
License: Apache License 2.0
Since Catala has a label system for rules, these labels should be clickable and interactive in the literate programming backends.
This involves modifying the src/catala/literate/html.ml
and src/catala/latex.ml
files. In order to know to which label redirect the links, we might want to change src/catala/driver.ml
to do the name resolution pass before generating the literate programming backends. Indeed, the name resolution context will contain information necessary to resolve the label linking.
Let us say you're dealing with a household, that can have many children. Here are your scopes and structures :
declaration structure Child :
data child_foo content integer
data child_bar content bool depends on amount
declaration scope HouseHold :
context household_foo content integer
context children content collection Child
declaration scope ChildScope :
context child content Child
scope ChildScope :
definition child_foo equals 42
definition child_bar of revenue equals revenue >= $1,000
We want that the rules of the scope ChildScope
apply for each child of the children
context variable, which is a collection. There is no language mechanism in Catala to let you do that other than to include inside HouseHold
another user-defined scope, MultipleChildrenScope
:
declaration scope MultipleChildrenScope :
context multiple_children content collection Child
context child_foo content integer depends on Child
context child_bar content bool depends on amount depends on Child
scope MultipleChildrenScope :
definition child_foo of child under condition
child in multiple_children
consequence equals
???
But then, what can you put here ? You need a way to have a copy of ChildScope
for every child in the list. There is currently no surface language concept for doing that. What we need here is some kind of "scope functor".
Scopes are actually translated into functions later in the compiler, so we have a way to backport this functional semantic into the surface language to make appear those scope functors. We could have something like that :
declaration scope MultipleChildrenScope :
...
context child_scope scope ChildScope depends on child
The last child
here is the name of the context parameter of ChildScope
. Then, inside your expressions you can invoke the functor :
scope MultipleChildrenScope :
definition child_foo of child under condition
child in multiple_children
consequence equals
(child_scope of child).child_foo
Inside the compiler, this means that child_scope
cannot be inlined statically anymore, since the function that it now represents will be called dynamically. Sub-scope inlining may not be the rule after all.
Right now, the only abstraction mechanism in Catala are the scopes, which correspond roughly to functions. However, as programs get bigger and bigger, we will want to group functions into modules in order to split and compartmentalize implementations.
Even though it is possible to split an implementation across multiple files currently, this can only be done via a primitive textual include mechanism that should ultimately be complemented by a proper module system.
This proposal is heavily inspired from the F* and Rust module system. Each file is its own module. The name of the module is introduced at the top of the file with the syntax (taking #84 into account):
> Module Foo
The name of the file must correspond to the ASCII snake case version of the module name.
Scopes and types declared in a module can be accessed without prefix in the same module. To use types and scopes declared and defined in other module Bar
, insert at the top of the file:
> Using Bar
Then simply refer to Bar
's scopes and types with Bar.<name of type/scope>
. Important: it is impossible to add rules and definitions to Bar
inside Foo
via a scope Bar: ...
.
Prefixes can be omitted for certain modules with the mention
> Using Bar implicit
For scopes or types with names defined in two distinct implicit
modules, name resolution selects the one corresponding to the last implicit
when traversing the file top to bottom.
Local aliases can be defined for modules with
> Using Bar as B
When invoking the compiler with catala bar.catala_en
, the compiler retrieves the list of the names external modules used in bar.catala_en
and proceeds to find .catala_en
files corresponding to those module names in the current directory. Additional lookup directories can be added with the -I
option.
For the OCaml backend and future backends, each Catala module should be translated to a different target language file. Hence, the -o
option should take an output directory instead of file and the generated files names should be the same as the source files, but with a different extension.
When invoking Catala to produce a literate programming output from a particular file, the output should only contain that single file and not the modules on which this file depends. To produce a literate programming output containing multiple files, one can uss the master file and dependencies list syntax like
catala/examples/us_tax_code/us_tax_code.catala_en
Lines 1 to 9 in 9282e5e
The implementation of this module system is going to vastly affect the compiler code. First, programs in the different intermediate representations should be represented as a list of modules (each of them containing types and scopes). The list should be ordered according to the topological order of the dependency graph between modules, which will have to be constructed. Cyclic dependencies between modules are forbidden. The passage to a collections of modules to an ordered list can be implemented in the surface -> desugared
translation.
When parsing expressions like <expression>.x.y
that are transformed into Dotted
catala/src/catala/surface/ast.mli
Lines 151 to 152 in 9282e5e
x
and y
should be resolved in that order:
Dotted
qualifier that can be a scope or a type belonging to that moduleDotted
qualifier containing a field name belonging to that structBefore starting this implementation, fixing #47 seems to be a good pre-requisite as we don't want to bother with ordering the types and scopes declaration correctly as long as they are cycle-free.
Leftover of #73: src/catala/default_calculus/interpreter.ml
use src/catala/runtime.ml
have very similar code, the former should use the latter as a dependency ot avoid duplication.
In this issue, we assume that Catala has a module system as described in #88. The problem we want to solve is exemplified by #81: we want for Catala programs to rely on abstract scopes and types which cannot be defined or implemented within the limits of the DSL.
To simplify the implementation, we only allow for whole modules to be externally implemented at a time. Externally implemented modules have to be define in standard .catala*
files, except that the first line with the module name should bear:
> Module Foo external
While types and scopes have to be declared in such a file, it is impossible to write any scope usage that might introduce rules or definitions. Modules that use Foo
can then use any of the externally implemented types and scopes defined in Foo
.
When compiling an externally implemented module to a backend like OCaml, the Catala compiler shall create a header file like *.mli
or *.h
. It is then up to the user to provide a manually-written implementation in the target language.
See below
Conditions are special because they have a "false" default value. This needs to be inserted somewhere like desugared_to_scope.ml
.
To make things prettier. Involves modifying src/catala/literate/{html.ml, latex.ml}
.
Currently, it is possible in Catala for structs to share field names and for enums to share constructor names. E.g:
declaration structure Foo:
data field1 content int
data field2 content bool
declaration structure Bar:
data field1 content date
data field3 content bool
But then, field access becomes ambiguous:
... baz.field1 # Is it Foo.field1 or Bar.field1 ?
Right now, an error is thrown in this case:
catala/src/catala/catala_surface/desugaring.ml
Lines 58 to 84 in 5973c67
catala/src/catala/catala_surface/desugaring.ml
Lines 232 to 243 in 5973c67
However, it is not currently syntactically possible to disambiguate using Foo.field1
or Bar.field1
; currently, the only solution is to rename the fields.
First, the parser has to be updated here:
catala/src/catala/catala_surface/parser.mly
Lines 115 to 117 in 5973c67
ident
should be turned into something like option(constructor DOT) ident
and the AST should be updated accordingly:
https://github.com/CatalaLang/catala/blob/master/src/catala/catala_surface/ast.ml#L266
Then, the desugaring should be updated. I don't known at this point whether we would need to update this part
catala/src/catala/catala_surface/desugaring.ml
Lines 208 to 245 in 5973c67
Although written with much care, the algorithm to unflatten the exception structures of the rules into a tree does not work correctly :
catala/src/catala/desugared/desugared_to_scope.ml
Lines 31 to 92 in ea117d1
The algorithm works as expected if there is only one base case and one or more exceptions to that base case, but fails when there are exceptions of exceptions.
This test case should return 2 for x
:
catala/tests/test_exception/exceptions_squared.catala
Lines 1 to 17 in ea117d1
But right now it squeezes the 1
and 2
cases as exceptions for the 0
case.
def_map_to_tree
should be completely rewritten in a clean way by constructing the actual graph of the exception structure for each variable. This graph can then be checked for cycle, solving #60. Then, the tree structure should be extracted by doing a graph traversal.
Hello,
On the first screenshot, code example states date as 31 december 1920, but code makes a check on 01/31/1920.
Currently, the operators for handling collections are insufficient to implement this function required for Section 121 of the US Tax Code:
catala/examples/us_tax_code/section_121.catala_en
Lines 14 to 22 in 494ba82
We clearly need a fully fledged standard library for collections. Even, it is unclear which functions would be sufficient to implement such an algorithm.
This situation is the usual DSL trap where we don't have the power of a full language to implement what we need. Multiple ways to get out of it:
merge_periods
functions to an input of the algorithm; this has the downside of not being able to write and run test cases in fully Catala.I would favor the first solution, and am listening for proposals on how to setup such an extensible system :)
The Catala surface syntax contains a handy sugar that allows to check whether a value of a sum type falls into one of the sum type cases:
catala/src/catala/catala_surface/ast.ml
Line 132 in 933fd02
This AST pattern is not handled by desugaring yet:
The desugaring should be implemented in the following way. Suppose you have:
declaration enumeration Foo:
-- Case1
-- Case2
-- Case3 content integer
Then x with pattern Case2
should be desugared to:
match x with pattern
-- Case1 : false
-- Case2: true
-- Case3 content y: false
One can take inspiration from
catala/src/catala/catala_surface/desugaring.ml
Lines 259 to 343 in 933fd02
Just writing this down so that it doesn't get lost. Denis wrote syntax highlighting using this technology:
https://github.com/CatalaLang/catala/blob/master/syntax_highlighting/en/catala_en.iro
which conceivably can then output syntax highlighting files for multiple languages:
Unfortunately, vim is not supported so it looks like writing the syntax.vim file for catala by hand is our best bet.
The language does not have any polymorphism right now. Support for polymorphism should be added in the default calculus representation via a classic Big-Lambda type abstraction with type variables. Big lambdas should be explicitly annotated in order to avoid big-lambda inference in the type checking algorithm.
Then, the polymorphism should be reflected upwards in the intermediate representations, and reflected as minimally as possible in the surface syntax. In a first thought, surface syntax should not change at all.
The implementation of the allocations familiales is not yet finished. Among other things, the function for computing the eldest child in the list of children is missing.
catala/examples/allocations_familiales/metadata.catala_fr
Lines 89 to 91 in 933fd02
A correct implementation would have to build at least on #52, but it would certainly also require an argmax/argmin
functionnality since two children might have the exact same age, and we have to arbitrarily pick between the two of them.
Right now, name resolution is done in two passes (in file src/catala/catala_surface/name_resolution.ml
):
This is nice but lacks flexibility for scope, structs and enums. Especially, we want users to be able to declare their scope anywhere in the code, and not following a dependency order. For instance, if scope A
has a subscope of type B
, we don't want to force the user to declare B
before A
.
This problem can be solved by doing a three-pass name resolution with the following passes:
Right now, only the section 132 of the US Tax code example typechecks in Catala. Concerning the other sections :
Sections that typecheck should also be unit-tested on the model of section 132.
Update the English and French versions of the tutorial with a chapter about collections : the collection
type, aggregation functions, length, etc.
Right now, the following test:
catala/tests/test_enum/quick_pattern_3.catala
Lines 4 to 18 in 9c795b5
Has the following output in the Catala interpreter :
catala/tests/test_enum/quick_pattern_3.catala.A.out
Lines 1 to 3 in 9c795b5
This is a weird behavior and should be changed. It should return a type error saying that Case3
is not in the enum of x
(that has only Case1
and Case2
.
Because in the default calculus representation, I implement structural typing. Indeed, structs and enums hasve been desugared into plain product and sum types. This means that if two enums have the same structure (same number of fields of the same type in the same order), then they can be used interchangeably, hence the current interpreter result.
This should change, as it is confusing for users. In order to change these default calculus AST cases:
catala/src/catala/default_calculus/ast.ml
Lines 89 to 96 in 9c795b5
And add to each case a Scopelang.StructName.t
and Scopelang.EnumName.t
that correspond to the name of the struct/enum that is being introduced or eliminated. By doing that, the typechecking algorithm can check whether the enum or struct name match.
The struct and enum name is available at the right point in the scope language, so I expect changes in the translation to happen only here :
catala/src/catala/scope_language/scope_to_dcalc.ml
Lines 86 to 195 in 9c795b5
Right now, the surface Catala AST mixes code items as well as literate programming headings and items : https://github.com/CatalaLang/catala/blob/master/src/catala/catala_surface/catala_ast.ml#L192. This makes it uneasy to determine to which "legislative atom" a chunk of code belongs to.
Indeed, if we are to compile Catala programs into programs that can explain why they got to their results, we should be able to link a position in a code block with a reference to a legislative atom: an article for French text, a code section for English texts, etc.
In order to do that, we need to change the flat structure of program_item
into a tree-shaped structure where the headings and atom title would be nodes of the tree, and the code blocks would be the leaves. Then, when desugaring the AST, we can augment Pos.t
with the additional information like Legislative Code XXX -- Section YYY --- Paragraph ZZZ -- ...
The main mission is to refactor Catala_ast.program_item
into something more like :
type program_item =
| CodeBlock of code_block
| LawTex of law_text
type program_node =
| LawHeading of string * int * program_item list
| LawArticle of law_article * program_item list
Then, the parser and especially this rule https://github.com/CatalaLang/catala/blob/master/src/catala/catala_surface/parser.mly#L500 should be updated accordingly. Finally, Pos.t
should be augmented with the information of the path of program_nodes
leading to the chunk of code.
Once #36 is solved, we can add a primitive polymorphic collection type into the language with its associated operators. This type should be present all the way from the surface syntax to the default calculus.
Once this type is added, the open question of #17 should be reactivated; maybe with a special map
operator that maps a scope (viewed as a function) onto a collection.
Collections are fixed-length arrays, whose length can be provided at runtime. Their natural extraction target are C arrays.
Catala supports maximum
and minimum
aggregation functions for collections. Right now, these are only present in the surface syntax.
One has to fill the holes like this one :
catala/src/catala/catala_surface/desugaring.ml
Lines 362 to 364 in 933fd02
To do that, the expression maximum money for salary in salaries of (salary - $200)
should desugar to
fold (fun acc salary -> let tmp = (salary - 200) in if acc < tmp then tmp else acc) <INIT> salaries
The problem lies within the <INIT>
expression. What to put here? I guess this should be provided by the user, so we have to update the syntax to something like maximum money context $0 for salary in salaries of (salary - $200)
Right now, the example test/test_func/func.catala
is not passing. It fails on this assertion : https://github.com/CatalaLang/catala/blob/master/src/catala/lambda_calculus/lambda_interpreter.ml#L193.
This assertion is triggered because the default for the f
wraps functions inside its justifications and consequences, as it's written here : https://github.com/CatalaLang/catala/blob/master/src/catala/catala_surface/desugaring.ml#L105. @nchataing you had set up things in a different manner but I changed them during the rewrite.
So two choices here :
I'm done implementing for the week-end, so if somebody wants to pick up here please do :)
In the old syntax, the following was accepted:
@§286-136 Penalty@
/*
scope Penalty286_83_135:
rule fine_ok under condition min_fine <=$ fine and fine <=$ max_fine
but with the new syntax, it seems to be rejected:
## §286-136 Penalty
```catala
scope Penalty286_83_135:
with error:
[ERROR] Syntax error at token "```catala"
[ERROR] Message: expected an article title, another heading or some text
[ERROR]
[ERROR] Error token:
[ERROR] --> Title17-MotorAndOtherVehicles.catala_en
[ERROR] |
[ERROR] 58 | ```catala
[ERROR] | ^^^^^^^^^
[ERROR] +
[ERROR]
[ERROR] Last good token:
[ERROR] --> Title17-MotorAndOtherVehicles.catala_en
[ERROR] |
[ERROR] 56 | ## §286-136 Penalty
[ERROR] | ^^^^^^^^^^^^^^^^^^^
[ERROR] 57 |
[ERROR] |
[ERROR] 58 | ```catala
[ERROR] | ^
[ERROR] +
make: *** [Title17-MotorAndOtherVehicles.run] Error 1
Inspired from C#. This expression:
e is P x && e'
Should desugar to
match e with P x -> e' | _ -> false
Right now, only the tutorial and the examples are reliable sources of documentation for the Catala syntax. https://catala-lang.org/en/formalisation contains a dump of the Catala grammar but with abstract tokens that are not tied to actual French or English keywords.
A better documentation should include a French and English syntax cheat sheet listing all the operators and structures available. A good way to build such a cheat sheet is to simply go through src/catala/catala_surface/ast.ml
and do all the cases for expressions, operators, scopes, etc.
Is there an automated way of doing that for OCaml ? I guess not.
The Code général des impôts example is just a stub at this point : https://github.com/CatalaLang/catala/tree/master/examples/code_general_impots.
It should be expanded with small-scoped but meaningful sections of the legislation that can be unit-tested in isolation.
Right now, builtin functions have a parser token associated with them:
catala/src/catala/catala_surface/parser.mly
Lines 147 to 158 in 7a835ac
Altough this allows supporting multi-language frontends out of the box, it is cumbersome since it requires touching the parser each time we want to add a new builtin.
Instead, we should add a piece of code in the qident
expression constructor:
catala/src/catala/catala_surface/parser.mly
Line 107 in 7a835ac
This piece of code would check would lookup the parser identifier into a multi-language list of identifiers corresponding to builtin functions, that would sit in the lexer*.ml
files. Careful, one also has to check that we can't define scope parameters, structure fields or bound variables with a name corresponding to a builtin
.
jonathan@absinthe:~/Code/catala/examples/us_tax_code (master) $ make
latexmk -f -C us_tax_code.tex
Latexmk: This is Latexmk, John Collins, 26 Dec. 2019, version: 4.67.
Latexmk: Could not find file 'us_tax_code.tex'
rm -rf us_tax_code.tex \
us_tax_code.d \
_minted-us_tax_code \
us_tax_code.html
This is because GNU make picks the first non-pattern rule to be the default target, in this case, the clean
target. I suggest adding an all
target at the beginning, and pick a suitable default; alternatively, the all
target could print a help message with a few suggested targets.
Right now, date literals are of the form |01/01/2021|
in Catala. However, this format is confusing because Americans use the MM/DD/YYYY
format instead of the logical DD/MM/YYYY
format.
To remove this source of confusion, we should adopt the ISO format and write |YYYY-MM-DD|
.
This is the code responsible for date literal parsing:
catala/src/catala/surface/parser.mly
Lines 187 to 193 in 83ac877
It should be tweaked to implement the ISO format separated by dashes instead of DIV
.
For instance:
(** This file has been generated by the Catala compiler, do not edit! *)
open Runtime
[@@@ocaml.warning "-26-27"]
type period = {
begin: date;
end: date;
}
note how begin
and end
are both OCaml keywords.
When the code says :
assertion foo fixed by law
It would be good in the HTML output to create a link on law
to the law that defines foo
. To get this information, one could alternatively :
Similar to the other .mld
files in the folders of each intermediate representation, the lambda calculus should have its own .mld
and appear in the general documentation diagram :
Lines 13 to 47 in af8a7b1
The help suggests Html
but the code only accepts HTML
; also, the capitalization of LaTeX
makes it kinda hard to get it right.
Currently, all the examples in the README are in French. It can be intimidated for English speakers.
On the landing page of the website, there is an example in English (Qualified employee discount), which could be added to the README.
Currently, the default calculus representation is translated to a lambda calculus with exceptions, according to a scheme described in section 4.3 of the Catala paper. This translation scheme has an advantage and a drawback:
The current translation scheme is implemented here:
catala/src/catala/lcalc/compile_with_exceptions.ml
Lines 38 to 111 in 611ef23
For Catala to target imperative low-level languages likes C, we have to eliminate catchable exceptions which are not supported in those languages. In generality, it is not possible to do so without an exception runtime. But there might be a possibility to get away without catchable exceptions to translate the default calculus programs generated by the Catala compiler.
Indeed, there is a structural invariant that is respected by default calculus programs generated by the Catala compiler. As a reminder, default calculus programs have a default term of the form < e_1, ..., e_n | e_{just} :- e_{cons} >
. The invariant can be expressed as follows: if a program e
is generated from the Catala compiler, then the default terms contained in e
are of the form X
, described by < e_1, ..., e_n | e_{just} :- e_{cons} >
where e_1
,..., e_n
are of the form X
and e_{just}
and e_{cons}
do not contain any defaults. Furthermore, all default terms of form X
are encapsulated at the toplevel by a error_if_empty
call that aborts if the argument is EmptyError
.
Because of this structural invariant, we can propose a 2-phase compilation scheme. In the first general phase, the translation is the identity as long as you don't encounter a default term. But when you encounter a default term of form X
encapsulated by error_if_empty
, then you enter phase 2 of the compilation scheme. The term to translate is akin to a default tree where all the leaves e_{just}
and e_{cons}
can be compiled using phase 1, since they supposedly don't contain any default term. Then, the default tree can be compiled recursively using a pure option
type instead of an exception to translate the EmptyError
case, on the model of process_exceptions
of section 4.3 of the Catala paper. The case where two exceptions conflicts will still have to be translated using a non-catchable exception, but non-catchable exceptions are fine for languages like C where they can be translated as return
.
This new compilation scheme can be implemented in the file src/catala/lcalc/compile_without_exceptions.ml
.
To be fixed by cleaning up the parser...
This does not parse (need to make not bind tighter):
exception definition max_days under condition
paragraph_a_applies and
not paragraph_b_applies and
Associativity for = and != is not left
Will add more as I find them
jonathan@absinthe:~/Code/catala/examples/us_tax_code (master) $ make section_121.run --debug
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for i386-apple-darwin11.3.0
Reading makefiles...
Updating goal targets....
File `section_121.run' does not exist.
Must remake target `section_121.run'.
dune exec --no-print-director ../../src/catala/catala.exe -- --language=en Makefile section_121.catala_en
dune exec --no-print-director ../../src/catala/catala.exe -- --language=en \
Interpret \
-s \
section_121.catala_en
catala: required argument FILE is missing
Usage: catala [OPTION]... BACKEND FILE
Try `catala --help' for more information.
make: *** [section_121.run] Error 1
not sure there's a good way of dealing with this, except perhaps
SCOPE?=PleasePickADefaultScopeViaTheSCOPEVariable
in the shared Makefile
Right now, the literate programming syntax of Catala uses the following operators:
@@
to open and close headings (with +
for precedence)@
to open and close article titles/*
and */
to delimit code sectionsThis syntax is non-standard and does not display well anywhere. Since we have to pick a syntax, might as well pick one that enhances interoperability with existing tools.
Markdown seems adapted to the level of formatting that we want for the legislative part. Plus, it's supported by most IDEs and has special GitHub/Gitlab support so it would help the display on the CVS.
With a markdown syntax, a Catala file could look like:
## Some law header
### Some law header subsection
#### [Article 6 ]
```
declaration structure:
...
```
The [...]
notation is used to distinguish law headers from titles of legislative article. An article is the atom of legislation, all the code blocks should belong to an article (see #29)
We need to change the parts of the lexers that deal with this syntax like
catala/src/catala/catala_surface/lexer.ml
Lines 539 to 585 in 7a835ac
From the top of my head no changes to the parser should be required. EDIT: BEGIN_CODE
and END_CODE
should be merged together I think ? Or we can say that BEGIN_CODE
should always be ```catala
whereas END_CODE
is ```
Right now, binary and unary operators are specialized depending on their type : +$
for money addition, -@
for date substraction, etc. This is cumbersome and ideally we would want to write +
for adding money, dates, integers, decimals, etc.
The need for specialized operators stems form Catala's type system, and more precisely from the default calculs typing algorithm. It uses a classical Hindley-Milner inference and the W algorithm. In classical Hindley-Milner inference, operators either operate on a fixed type, or are completely polymorphic. This is the typing procedure for Catala operators right now :
catala/src/catala/default_calculus/typing.ml
Lines 109 to 150 in 06803e4
Why can't we make all operators completely polymorphic ? Because it does not make any sense to +
two enumerations together, or *
two dates.
What we really want is a type system where we say : +
operates only on a fixed list of types. This corresponds to Hindley-Milner inference with constraints, a notoriously hard problem. Some libraries exist to perform the typing, like https://gitlab.inria.fr/fpottier/inferno, but overall it is much more complicated from the classical inference I'm doing right now.
Because I don't want to spend too much time on Catala's type system, I prefer we stick to classical inference and hence we're stuck with the default calculus operators as they are.
But this does not mean we can't have what we want ! Indeed, we can keep the differentiated default calculus operators but have undifferentiated surface syntax operator. We can write |01/01/2020| - |01/01/2019|
and have the compiler figure out that -
is actually -@
during desugaring.
This system is nice because it does not complicate the default calculus. Instead, we rely on a conservative desugaring pass that would sit somewhere in Desugared
or Scopelang
and that would specialize the operators with the information provided by a conservative, high-level additional type checking pass done in Desugared
or Scopelang
.
If this pass does not manage to determine the type of the operator, we send an error message back to the user saying that desambiguation is needed and the user actually has to write -@
.
What are your thoughts on this?
Right now, we have a label system to declare exceptions to rules :
catala/examples/tutorial_en/tutorial_en.catala_en
Lines 355 to 362 in 839310d
But in many cases, when defining variable x
of scope A
, you only have one base case and several exceptions to it. To make the syntax easier to read in this case, we could have a syntactic sugar of the form:
definition income_tax equals two_brackets.tax_formula of individual.income
# Then, you can declare the exception by referring back to the label
exception definition income_tax under condition
individual.income <=$ $10,000
consequence equals $0
The desugaring pass could make sure that there's only one definition
without the exception
tag, making it the base case. If there are multiple definition
without exception
, then the desugaring pass throws an error message saying you should revert to a label to disambiguate.
This involves modyfing src/catala/catala_surface/parser.mly
as well as src/catala/catala_surface/desugaring.ml
Looking at https://sammade.github.io/aloha-io/title-17/chapter-286/section-286-136/ it appears that an exclusive or is required for the final paragraph (c). Sounds like it would a worthwhile addition to Catala.
For the latest work on Section 121, there is a notion of a ratio of days of nonqualified use over days of ownership.
It would be convenient to have an operator /^: duration -> duration -> decimal
~/Documents/git/catala master* [13/4789]
❯ ./generate_website_assets.sh ../catala-website/assets
dune exec ../../src/catala.exe -- --debug --language=fr Makefile allocations_familiales.catala
Entering directory '/Users/nadim/Documents/git/catala'
Entering directory '/Users/nadim/Documents/git/catala'
[DEBUG] Reading files...
[DEBUG] Parsing allocations_familiales.catala
[DEBUG] Parsing ./metadata.catala
[DEBUG] Parsing ./securite_sociale_L.catala
[DEBUG] Parsing ./securite_sociale_R.catala
[DEBUG] Parsing ./securite_sociale_D.catala
[DEBUG] Parsing ./decrets_divers.catala
dune exec ../../src/catala.exe -- --debug --language=fr \
--wrap \
--pygmentize=../../syntax_highlighting/fr/pygments/pygments/env/bin/pygmentize \
HTML \
allocations_familiales.catala
Entering directory '/Users/nadim/Documents/git/catala'
Entering directory '/Users/nadim/Documents/git/catala'
[DEBUG] Reading files...
[DEBUG] Parsing allocations_familiales.catala
[DEBUG] Parsing ./metadata.catala
[DEBUG] Parsing ./securite_sociale_L.catala
[DEBUG] Parsing ./securite_sociale_R.catala
[DEBUG] Parsing ./securite_sociale_D.catala
[DEBUG] Parsing ./decrets_divers.catala
[DEBUG] Weaving literate program into HTML
[DEBUG] Pygmenting the code chunk in file ./metadata.catala, from 3:1 to 221:33
sh: ../../syntax_highlighting/fr/pygments/pygments/env/bin/pygmentize: No such file or directory
[ERROR] Weaving error: pygmentize command "../../syntax_highlighting/fr/pygments/pygments/env/bin/pygmentize -l catala_
fr -f html -O style=colorful,anchorlinenos=True,lineanchors="./metadata.catala",linenos=table,linenostart=3 -o /var/fol
ders/sy/c_zqf9w55vj6yzfq2yrbk_zw0000gn/T/catala_html_pygmentscf0964out /var/folders/sy/c_zqf9w55vj6yzfq2yrbk_zw0000gn/T
/catala_html_pygments2f2580in" returned with error code 127
make: *** [allocations_familiales.html] Error 255
dune exec ../../src/catala.exe -- --debug --language=en Makefile english.catala
Entering directory '/Users/nadim/Documents/git/catala'
Entering directory '/Users/nadim/Documents/git/catala'
[DEBUG] Reading files...
[DEBUG] Parsing english.catala
dune exec ../../src/catala.exe -- --debug --language=en \
--wrap \
--pygmentize=../../syntax_highlighting/en/pygments/pygments/env/bin/pygmentize \
HTML \
english.catala
Entering directory '/Users/nadim/Documents/git/catala'
Entering directory '/Users/nadim/Documents/git/catala'
[DEBUG] Reading files...
[DEBUG] Parsing english.catala
[DEBUG] Weaving literate program into HTML
[DEBUG] Pygmenting the code chunk in file english.catala, from 4:1 to 9:48
sh: ../../syntax_highlighting/en/pygments/pygments/env/bin/pygmentize: No such file or directory
[ERROR] Weaving error: pygmentize command "../../syntax_highlighting/en/pygments/pygments/env/bin/pygmentize -l catala_en -f html -O style=colorful,anchorlinenos=True,lineanchors="english.catala",linenos=table,linenostart=4 -o /var/folders/sy/c_zqf9w55vj6yzfq2yrbk_zw0000gn/T/catala_html_pygments927227out /var/folders/sy/c_zqf9w55vj6yzfq2yrbk_zw0000gn/T/catala_html_pygments07468ein" returned with error code 127
make: *** [english.html] Error 255
make: `grammar.html' is up to date.
make: `catala.html' is up to date.
make: `legifrance_catala.html' is up to date.
cp: examples/allocations_familiales/allocations_familiales.html: No such file or directory
cp: examples/dummy_english/english.html: No such file or directory
And yes, I did run the following before:
make install-dependencies
make build
make pygments
source syntax_highlighting/en/pygments/pygments/env/bin/activate
Right now the algorithm that builds the default tree from the list of rules defining a variable expects that there are no cycles in the label
and exception
declaration.
catala/src/catala/desugared/desugared_to_scope.ml
Lines 25 to 33 in 839310d
This requirement is not enforced, so we should built a dependency graph whose vertices are label
and edges are exception
, and check for cycles in this graph for each scope variable (defined by a list of rules).
The code for this graph checking could live in src/catala/desugared/dependency.ml
.
The documentation for writing Catala with French keywords is out of date, mainly some keywords are missing compared to the English version.
Per Denis' remarks in PR#23, the reading guide should be written as HTML rather than in LaTeX because we want it to appear here : https://catala-lang.org/en/guide. There's already a tutorial for programmer that showcases most of the syntax here : https://catala-lang.org/en/examples/tutorial.
I would imagine the English versions are considered the reference versions. If that is indeed the case, it might be easiest to simply translate the English versions, taking special care to maintain the French keywords as they are already used.
What do you think? If that is ok with you I can help out by doing some translation.
Right now they're parsed as variables.
Right now if we have :
declaration structure Foo :
data x content integer
data y content integer
We have no way inside a scope to build Foo { x = ... ; y = ... }
. We need to add that in the surface language.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.