Skip to content

Commit

Permalink
Progress on 2.3
Browse files Browse the repository at this point in the history
  • Loading branch information
denismerigoux committed Jan 28, 2025
1 parent b1b1c2f commit 50f8f31
Show file tree
Hide file tree
Showing 3 changed files with 219 additions and 5 deletions.
147 changes: 147 additions & 0 deletions examples/tutorial_end_2_3.catala_en
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
```catala
declaration structure Individual:
data income content money
data number_of_children content integer

declaration scope IncomeTaxComputation:
input current_date content date
input individual content Individual
input overseas_territories content boolean
internal tax_rate content decimal
output income_tax content money
```

## Article 1

The income tax for an individual is defined as a fixed percentage of the
individual's income over a year.

```catala
scope IncomeTaxComputation:
definition income_tax equals
individual.income * tax_rate
```

## Article 2 (old version before 2000)

The fixed percentage mentioned at article 1 is equal to 20 %.

```catala
scope IncomeTaxComputation:
label article_2
definition tax_rate under condition
current_date < |2000-01-01|
consequence equals 20%
```

## Article 2 (new version after 2000)

The fixed percentage mentioned at article 1 is equal to 21 % %.

```catala
scope IncomeTaxComputation:
# Simply use the same label "article_2" as the previous definition to group
# them together
label article_2
definition tax_rate under condition
current_date >= |2000-01-01|
consequence equals 21%
```

## Article 3

If the individual is in charge of 2 or more children, then the fixed
percentage mentioned at article 1 is equal to 15 %.

```catala
scope IncomeTaxComputation:
label article_3 exception article_2
definition tax_rate under condition
individual.number_of_children >= 2
consequence equals 15%
```

## Article 4

Individuals earning less than $10,000 are exempted of the income tax mentioned
at article 1.

```catala
scope IncomeTaxComputation:
label article_4 exception article_3
definition tax_rate under condition
individual.income <= $10,000
consequence equals 0%
```

## Article 5

Individuals earning more than $100,000 are subjects to a tax rate of
30%, regardless of their number of children.

```catala
scope IncomeTaxComputation:
label article_5 exception article_3
definition tax_rate under condition
individual.income > $100,000
consequence equals 30%
```

## Article 6

In the overseas territories, the tax rate for individuals earning
more than $100,000 specified at article 5 is reduced to 25 %.

```catala
scope IncomeTaxComputation:
label article_6 exception article_5
definition tax_rate under condition
individual.income > $100,000 and overseas_territories
consequence equals 25%
```

## Article 7

When several individuals live together, they are collectively subject to
the household tax. The household tax owed is $1000 per individual of the household,
and half the amount per children.

```catala
declaration scope HouseholdTaxComputation:
input individuals content list of Individual
output household_tax content money
```

```catala
scope HouseholdTaxComputation:
definition household_tax equals
let number_of_individuals equals number of individuals in
let number_of_children equals
sum integer
of individual.number_of_children for individual among individuals
in
$1000
* (
decimal of (number_of_children)
+ decimal of (number_of_children) / 2.0
)
```

## Test

```catala
declaration scope Test:
output computation content IncomeTaxComputation

scope Test:
definition computation equals
output of IncomeTaxComputation with {
-- individual:
Individual {
-- income: $20,000
-- number_of_children: 0
}
-- overseas_territories: false
-- current_date: |1999-01-01|
}
```
10 changes: 5 additions & 5 deletions src/2-1-basic-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,14 @@ For instance, Article 1 declares a scope for computing the income tax:

~~~admonish note title="Declaring a scope"
```catala
# Scope names use the CamelCase naming convention, like names of structs
# or enums Scope variables, on the other hand, use the snake_case naming
# convention, like struct fields.
declaration scope IncomeTaxComputation:
# Scope names use the CamelCase naming convention, like names of structs
# or enums Scope variables, on the other hand, use the snake_case naming
# convention, like struct fields.
input individual content Individual
# This line declares an input variable of the scope, which is akin to
# The following line declares an input variable of the scope, which is akin to
# a function parameter in computer science term. This is the piece of
# data on which the scope will operate.
input individual content Individual
internal tax_rate content decimal
output income_tax content money
```
Expand Down
67 changes: 67 additions & 0 deletions src/2-3-list-modular.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,70 @@ to execute the example is included below for reference.
~~~
~~~~~~

## Making a household from a list of invidivuals

Previously, the Catala Tutorial Tax Code (CTTC) has defined an income tax for
each individual and their children. But now, the CTTC is becoming greedier as a
new, separate tax similar to Thatcher's infamous [poll
tax](https://en.wikipedia.org/wiki/Poll_tax_(Great_Britain)). At its inception,
the household tax is such that each individual in a household is taxed a fixed
sum, with a reduced rate for the children:

~~~admonish quote title="Article 7"
When several individuals live together, they are collectively subject to
the household tax. The household tax owed is $1000 per individual of the household,
and half the amount per children.
~~~

Now, implementing this in Catala requires going beyond the
`IncomeTaxComputation` scope that we used earlier. Indeed, this new tax requires
a new scope, `HouseholdTaxComputation`! While it is fairly evident that the
`output` of this new scope should be the `household_tax`, its `input` is the
collection of individuals that make up the household.

Fortunately, Catala has a built-in type for collection of things, called `list`,
even though it behaves more like an array in traditionnal Computer Science
jargon.

~~~admonish note title="Declaring a new scope with a list input"
```catala
declaration scope HouseholdTaxComputation:
# The syntax "list of <X>" designates the type whose values are lists of
# elements with type <X>.
input individuals content list of Individual
output household_tax content money
```
~~~

To define `household_tax`, we must now:
1. count the number of individuals in `individuals`;
2. count the number of children in each individual and add these counts together;
3. multiply these counts by the right amount of tax.

We will perform each one of these steps in the body of the `definition` of
`household_tax`, in the scope `HouseholdTaxComputation`, using local
variables.

~~~admonish tip title="`internal` scope variables and local variables in definitions"
When a variable definition gets complex like above, it is often useful to
separate each step by defining intermediate variables. There are two ways
of doing that.
First, you can declare inside the scope declaration an extra scope variable
with the label `internal` instead of `input` or `output`, as seen in
the [first section of the tutorial](./2-1-basic-blocks.md).
Second, if you are confident that you will only need the intermediate variable
in the narrow context of a single scope variable definition, you can use a
local variable inside the definition of the scope variable. These local variables
are introduced and used with the following syntax:
```catala
# The following line defines local variable "x" as begin equal to 4 * 5
let x equals 4 * 5 in
# We can then use "x" after the "in" keyword in the rest of the code
x + 2
```
~~~

For the first step,

0 comments on commit 50f8f31

Please sign in to comment.