Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into ValentinLeTallec/ma…
Browse files Browse the repository at this point in the history
…ster
  • Loading branch information
sharkdp committed Oct 9, 2024
2 parents 89a141b + ced476b commit ac53ad5
Show file tree
Hide file tree
Showing 66 changed files with 2,218 additions and 550 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions book/build.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import subprocess
from pathlib import Path
import urllib.parse
import os


SCRIPT_DIR = Path(__file__).parent.resolve()
Expand All @@ -15,14 +16,14 @@ def generate_example(
print(path_out)

code = []
with open(path_in, "r") as fin:
with open(path_in, "r", encoding="utf-8") as fin:
for line in fin:
if not (strip_asserts and "assert_eq" in line):
code.append(line)

url = f"https://numbat.dev/?q={urllib.parse.quote_plus(''.join(code))}"

with open(path_out, "w") as fout:
with open(path_out, "w", encoding="utf-8") as fout:
fout.write("<!-- This file is autogenerated! Do not modify it -->\n")
fout.write("\n")
fout.write(f"# {title}\n")
Expand Down Expand Up @@ -80,7 +81,7 @@ def xkcd_footer(number, img_name):
)

path_units = SCRIPT_DIR / "src" / "list-units.md"
with open(path_units, "w") as f:
with open(path_units, "w", encoding="utf-8") as f:
print("Generating list of units...", flush=True)
subprocess.run(
["cargo", "run", "--release", "--quiet", "--example=inspect", "units"],
Expand All @@ -91,7 +92,7 @@ def xkcd_footer(number, img_name):

def list_of_functions(file_name, document):
path = SCRIPT_DIR / "src" / f"list-functions-{file_name}.md"
with open(path, "w") as f:
with open(path, "w", encoding="utf-8") as f:
print(f"# {document['title']}\n", file=f, flush=True)

if introduction := document.get("introduction"):
Expand Down Expand Up @@ -119,6 +120,8 @@ def list_of_functions(file_name, document):
print(
f"Generating list of functions for module '{module}'...", flush=True
)
env = os.environ.copy()
env["TZ"] = "UTC"
subprocess.run(
[
"cargo",
Expand All @@ -132,6 +135,7 @@ def list_of_functions(file_name, document):
],
stdout=f,
text=True,
env=env,
)


Expand Down
6 changes: 5 additions & 1 deletion book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
- [XKCD 687](./example-xkcd_687.md)
- [XKCD 2585](./example-xkcd_2585.md)
- [XKCD 2812](./example-xkcd_2812.md)
- [IDE / editor integration](./editor-integration.md)

# Numbat language reference

Expand Down Expand Up @@ -69,6 +68,11 @@

- [Type system](./type-system.md)

# Other topics

- [IDE / editor integration](./editor-integration.md)
- [Comparison with other tools](./comparison.md)

# Support

- [Contact us](./contact-us.md)
50 changes: 50 additions & 0 deletions book/src/comparison.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Comparison with other tools

The following table provides a comparison of Numbat with other scientific calculators and programming languages. This comparison
is certainly *not* objective, as we only list criteria that we consider important. If you think that a tool or language is missing
or misrepresented, please [let us know](https://github.com/sharkdp/numbat/issues).

| | Numbat | [Qalculate](https://qalculate.github.io/) | [Kalker](https://github.com/PaddiM8/kalker) | [GNU Units](https://www.gnu.org/software/units/) | [Frink](https://frinklang.org/) | [Wolfram Alpha](https://www.wolframalpha.com/) |
|----------------------------------------|-----------------|-----------|--------|-----------|-------|---------------|
| FOSS License | MIT, Apache-2.0 | GPL-2.0 | MIT | GPL-3.0 |||
| **Interfaces** | | | | | | |
| Command-line |||||||
| Web version |||||||
| Graphical ||||| (✓) ||
| **Units** | | | | | | |
| Comprehensive list of units |||||||
| Custom units |||||||
| Physical dimensions |||||||
| Currency conversions |||||||
| Date and time calculations |||||||
| **Language features** | | | | | | |
| Custom functions |||||||
| Real programming language |||||| ? |
| Strongly typed |||||||
| **Calculator features** | | | | | | |
| Symbolic calculations || (✓) ||| (✓) ||
| Hex/Oct/Bin mode |||||||
| Complex numbers | ❌ ([#180](https://github.com/sharkdp/numbat/issues/180)) ||||||
| Vectors, Matrices |||||||

## Detailed comparison

- [Qalculate](https://qalculate.github.io/) is a fantastic calculator with a strong support for units and conversions.
If you don't need the full power of a programming language, Qalculate is probably more feature-complete than Numbat.
- [Frink](https://frinklang.org/) is a special-purpose programming language with a focus on scientific calculations
and units of measurement. The language is probably more powerful than Numbat, but lacks a static type system. It's also
a imperative/OOP language, while Numbat is a functional/declarative language. Frink is not open-source.
- [GNU Units](https://www.gnu.org/software/units/) is probably the most comprehensive tool in terms of pre-defined units.
Numbat makes it very easy to define [custom units](./unit-definitions.md). If you think that a unit should be part
of the standard library, please [let us know](https://github.com/sharkdp/numbat/issues).
- [Wolfram Alpha](https://www.wolframalpha.com/) is a very powerful tool, but it's focused on single-line queries instead
of longer computations. The query language lacks a strict syntax (which some might consider a feature). The tool is not
open source and sometimes has limitations with respect to the number/size of queries you can make.

## Other interesting tools / languages

- [F#](https://fsharp.org/) is the only programming language that we know of that comes close in terms of having an
expressive type system that is based on units of measure. In fact, Numbats type system is heavily inspired by F#,
except that it uses physical dimensions instead of physical units on the type level. Both languages have feature
full [type inference](./function-definitions.md#type-inference). F# is not listed above, as it's not really suitable
as a scientific calculator.
2 changes: 1 addition & 1 deletion book/src/date-and-time.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ now() -> unixtime
# What is the date corresponding to a given UNIX timestamp?
from_unixtime(1707568901)
# How long are one million seconds in years, months, days, hours, minutes, seconds
# How long are one million seconds in years, months, days, hours, minutes, seconds?
1 million seconds -> human
```

Expand Down
136 changes: 136 additions & 0 deletions book/src/list-functions-datetime.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,41 +18,116 @@ Parses a string (date and time) into a `DateTime` object. See [here](./date-and-
fn datetime(input: String) -> DateTime
```

<details>
<summary>Examples</summary>

<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=datetime%28%222022%2D07%2D20T21%3A52%2B0200%22%29')""></button></div><code class="language-nbt hljs numbat">>>> datetime("2022-07-20T21:52+0200")

= 2022-07-20 19:52:00 UTC [DateTime]
</code></pre>

<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=datetime%28%222022%2D07%2D20%2021%3A52%20Europe%2FBerlin%22%29')""></button></div><code class="language-nbt hljs numbat">>>> datetime("2022-07-20 21:52 Europe/Berlin")

= 2022-07-20 21:52:00 CEST (UTC +02), Europe/Berlin [DateTime]
</code></pre>

<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=datetime%28%222022%2F07%2F20%2009%3A52%20PM%20%2B0200%22%29')""></button></div><code class="language-nbt hljs numbat">>>> datetime("2022/07/20 09:52 PM +0200")

= 2022-07-20 21:52:00 (UTC +02) [DateTime]
</code></pre>

</details>

### `format_datetime`
Formats a `DateTime` object as a string.

```nbt
fn format_datetime(format: String, input: DateTime) -> String
```

<details>
<summary>Examples</summary>

<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=format%5Fdatetime%28%22This%20is%20a%20date%20in%20%25B%20in%20the%20year%20%25Y%2E%22%2C%20datetime%28%222022%2D07%2D20%2021%3A52%20%2B0200%22%29%29')""></button></div><code class="language-nbt hljs numbat">>>> format_datetime("This is a date in %B in the year %Y.", datetime("2022-07-20 21:52 +0200"))

= "This is a date in July in the year 2022." [String]
</code></pre>

</details>

### `get_local_timezone`
Returns the users local timezone.

```nbt
fn get_local_timezone() -> String
```

<details>
<summary>Examples</summary>

<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=get%5Flocal%5Ftimezone%28%29')""></button></div><code class="language-nbt hljs numbat">>>> get_local_timezone()

= "UTC" [String]
</code></pre>

</details>

### `tz`
Returns a timezone conversion function, typically used with the conversion operator.

```nbt
fn tz(tz: String) -> Fn[(DateTime) -> DateTime]
```

<details>
<summary>Examples</summary>

<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=datetime%28%222022%2D07%2D20%2021%3A52%20%2B0200%22%29%20%2D%3E%20tz%28%22Europe%2FAmsterdam%22%29')""></button></div><code class="language-nbt hljs numbat">>>> datetime("2022-07-20 21:52 +0200") -> tz("Europe/Amsterdam")

= 2022-07-20 21:52:00 CEST (UTC +02), Europe/Amsterdam [DateTime]
</code></pre>

<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=datetime%28%222022%2D07%2D20%2021%3A52%20%2B0200%22%29%20%2D%3E%20tz%28%22Asia%2FTaipei%22%29')""></button></div><code class="language-nbt hljs numbat">>>> datetime("2022-07-20 21:52 +0200") -> tz("Asia/Taipei")

= 2022-07-21 03:52:00 CST (UTC +08), Asia/Taipei [DateTime]
</code></pre>

</details>

### `unixtime`
Converts a `DateTime` to a UNIX timestamp. Can be used on the right hand side of a conversion operator: `now() -> unixtime`.

```nbt
fn unixtime(input: DateTime) -> Scalar
```

<details>
<summary>Examples</summary>

<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=datetime%28%222022%2D07%2D20%2021%3A52%20%2B0200%22%29%20%2D%3E%20unixtime')""></button></div><code class="language-nbt hljs numbat">>>> datetime("2022-07-20 21:52 +0200") -> unixtime

= 1_658_346_720
</code></pre>

</details>

### `from_unixtime`
Converts a UNIX timestamp to a `DateTime` object.

```nbt
fn from_unixtime(input: Scalar) -> DateTime
```

<details>
<summary>Examples</summary>

<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=from%5Funixtime%282%5E31%29')""></button></div><code class="language-nbt hljs numbat">>>> from_unixtime(2^31)

= 2038-01-19 03:14:08 UTC [DateTime]
</code></pre>

</details>

### `today`
Returns the current date at midnight (in the local time).

Expand All @@ -67,6 +142,16 @@ Parses a string (only date) into a `DateTime` object.
fn date(input: String) -> DateTime
```

<details>
<summary>Examples</summary>

<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=date%28%222022%2D07%2D20%22%29')""></button></div><code class="language-nbt hljs numbat">>>> date("2022-07-20")

= 2022-07-20 00:00:00 UTC [DateTime]
</code></pre>

</details>

### `time`
Parses a string (time only) into a `DateTime` object.

Expand All @@ -81,20 +166,50 @@ Adds the given time span to a `DateTime`. This uses leap-year and DST-aware cale
fn calendar_add(dt: DateTime, span: Time) -> DateTime
```

<details>
<summary>Examples</summary>

<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=calendar%5Fadd%28datetime%28%222022%2D07%2D20%2021%3A52%20%2B0200%22%29%2C%202%20years%29')""></button></div><code class="language-nbt hljs numbat">>>> calendar_add(datetime("2022-07-20 21:52 +0200"), 2 years)

= 2024-07-20 21:52:00 (UTC +02) [DateTime]
</code></pre>

</details>

### `calendar_sub`
Subtract the given time span from a `DateTime`. This uses leap-year and DST-aware calendar arithmetic with variable-length days, months, and years.

```nbt
fn calendar_sub(dt: DateTime, span: Time) -> DateTime
```

<details>
<summary>Examples</summary>

<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=calendar%5Fsub%28datetime%28%222022%2D07%2D20%2021%3A52%20%2B0200%22%29%2C%203%20years%29')""></button></div><code class="language-nbt hljs numbat">>>> calendar_sub(datetime("2022-07-20 21:52 +0200"), 3 years)

= 2019-07-20 21:52:00 (UTC +02) [DateTime]
</code></pre>

</details>

### `weekday`
Get the day of the week from a given `DateTime`.

```nbt
fn weekday(dt: DateTime) -> String
```

<details>
<summary>Examples</summary>

<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=weekday%28datetime%28%222022%2D07%2D20%2021%3A52%20%2B0200%22%29%29')""></button></div><code class="language-nbt hljs numbat">>>> weekday(datetime("2022-07-20 21:52 +0200"))

= "Wednesday" [String]
</code></pre>

</details>

### `julian_date` (Julian date)
Convert a `DateTime` to a Julian date, the number of days since the origin of the Julian date system (noon on November 24, 4714 BC in the proleptic Gregorian calendar).
More information [here](https://en.wikipedia.org/wiki/Julian_day).
Expand All @@ -103,6 +218,16 @@ More information [here](https://en.wikipedia.org/wiki/Julian_day).
fn julian_date(dt: DateTime) -> Time
```

<details>
<summary>Examples</summary>

<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=julian%5Fdate%28datetime%28%222022%2D07%2D20%2021%3A52%20%2B0200%22%29%29')""></button></div><code class="language-nbt hljs numbat">>>> julian_date(datetime("2022-07-20 21:52 +0200"))

= 2.45978e+6 day [Time]
</code></pre>

</details>

### `human` (Human-readable time duration)
Converts a time duration to a human-readable string in days, hours, minutes and seconds.
More information [here](https://numbat.dev/doc/date-and-time.html).
Expand All @@ -111,3 +236,14 @@ More information [here](https://numbat.dev/doc/date-and-time.html).
fn human(time: Time) -> String
```

<details>
<summary>Examples</summary>

How long is a microcentury?
<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=century%2F1e6%20%2D%3E%20human')""></button></div><code class="language-nbt hljs numbat">>>> century/1e6 -> human

= "52 minutes + 35.693 seconds" [String]
</code></pre>

</details>

Loading

0 comments on commit ac53ad5

Please sign in to comment.