Fin Text Format

unstable

A general purpose notation for data interchange.

Specification Builtins Roadmap Code

Gaps

Symbols

examples = [
  # symbols
  foo, foo_bar, _98, foo_, _98_, _ 
  :key, crypto:sha256, :a:b:c:_:_98_
]

Numbers

examples = [
  # numbers
  98, 1.23e4, -42, 0, 84e0
  0.55, -0.123e-4, -0.00
]

Strings

Escaped Strings

examples = [
  ""
  "fin 🐬"
  "escape sequences \\ \" \t \n \r \u{7f}"
]

Raw Strings

examples = [
  |a raw string
 
  |raw strings are not interpreted.
  |  - unescaped \n, #not a comment, 
  |  - this bar | is part of the string.
  |can span multiple lines.

  |another raw string 🐬
  |this one ends with a line feed
  |

  # below is an empty raw string
  |
]

Comments

# comments can span multiple 
# lines just like raw strings

# unlike raw strings they're not values. 🐬

Arrays

expanded_array = [

  # expanded array elements are indented with tabs.
  # consecutive empty lines are removed.

  # comma is used to separate values on the same line.
  a, 98, [
    # commas can be used pre/post expanded notation.
    | comments and raw strings trigger expansion.
  ], "foo"

  # for inline arrays - elements are comma separated
  # on the same line as the surrounding brackets
  [], tagged["array"], [98, goal, []]

]

Maps

expanded_map = (

  # like arrays expanded map elements are indented with tabs.
  # consecutive empty lines are removed.

  # comma is used to separate entries on the same line.
  a = b, 1 = "two"

  # keys and vals can also be other collections
  # inline maps have entries on the same line comma separated
  () = tag(cb = 98, kk = 55)
)

Map Entries

# example map entries
# most keys in the wild are symbols, strings or numbers
# however, fin supports all value types as keys

# inline-inline
a = 98, nested = (a = 98) 

# inline-block
b =
|raw

# block-inline
|c
= 98

# block-block
|d
= 
|e

(
  # key is an expanded map
  a = 98
) = [ 
  # val is an expanded array
], f =
| line continuation (comma) works
| after expanded vals & before expanded keys

Top Level Value

Extensions

extensions = [

  # builtin extensions (start with fin:)
  fin:timestamp["2024-02-26T03:01:13.644Z"]
  fin:bytes[
    |f6 69 6e 20 54 d6 78 74
    |2a 46 6f 72 6d 61 74 0a
  ]
  fin:uuid["c83ccbb6-44d0-4d62-8263-b8afec01f3a2"]

  # booleans are builtins
  true, false

  # extensions ending with _ are discarded
  fin:_(is_value = false, treated_as = "comment")

  # custom extensions (start with ext:)
  ext:null, ext:nan, ext:int:hex_10fe
  ext:loc(x = 1, y = 2) 
  ext:markdown[
    |# title 
    |
    |a **markdown** extension!
  ]
]