{"id":13556803,"url":"https://github.com/edn-format/edn","last_synced_at":"2025-05-15T13:09:08.851Z","repository":{"id":4563682,"uuid":"5704869","full_name":"edn-format/edn","owner":"edn-format","description":"Extensible Data Notation","archived":false,"fork":false,"pushed_at":"2022-01-15T06:14:47.000Z","size":359,"stargazers_count":2653,"open_issues_count":26,"forks_count":96,"subscribers_count":98,"default_branch":"master","last_synced_at":"2025-04-13T14:09:15.569Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/edn-format.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-09-06T16:09:46.000Z","updated_at":"2025-04-12T18:05:48.000Z","dependencies_parsed_at":"2022-07-12T15:01:11.004Z","dependency_job_id":null,"html_url":"https://github.com/edn-format/edn","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edn-format%2Fedn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edn-format%2Fedn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edn-format%2Fedn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edn-format%2Fedn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/edn-format","download_url":"https://codeload.github.com/edn-format/edn/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254346623,"owners_count":22055808,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T12:04:01.889Z","updated_at":"2025-05-15T13:09:03.843Z","avatar_url":"https://github.com/edn-format.png","language":null,"funding_links":[],"categories":["Others","others","Misc"],"sub_categories":[],"readme":"edn\n===\n\nextensible data notation [eed-n]\n\n# Rationale\n\n**edn** is an extensible data notation. A superset of **edn** is used by Clojure to represent\nprograms, and it is used by Datomic and other applications as a data transfer format. This spec\ndescribes **edn** in isolation from those and other specific use cases, to help facilitate\nimplementation of readers and writers in other languages, and for other uses.\n\n**edn** supports a rich set of built-in elements, and the definition of extension elements in terms\nof the others. Users of data formats without such facilities must rely on either convention or\ncontext to convey elements not included in the base set. This greatly complicates application\nlogic, betraying the apparent simplicity of the format. **edn** is simple, yet powerful enough to\nmeet the demands of applications without convention or complex context-sensitive logic.\n\n**edn** is a system for the conveyance of _values_. It is not a type system, and has no schemas.\nNor is it a system for representing objects - there are no reference types, nor should a consumer\nhave an expectation that two equivalent elements in some body of **edn** will yield distinct object\nidentities when read, unless a reader implementation goes out of its way to make such a promise.\nThus the resulting values should be considered immutable, and a reader implementation should yield\nvalues that ensure this, to the extent possible.\n\n**edn** is a set of definitions for acceptable _elements_. A use of **edn** might be a stream or\nfile containing elements, but it could be as small as the conveyance of a single element in e.g. an\nHTTP query param.\n\nThere is no enclosing element at the top level. Thus **edn** is suitable for streaming and\ninteractive applications.\n\nThe base set of elements in **edn** is meant to cover the basic set of data structures common to\nmost programming languages. While **edn** specifies how those elements are formatted in text, it\ndoes not dictate the representation that results on the consumer side. A well behaved reader\nlibrary should endeavor to map the elements to programming language types with similar semantics.\n\n# Spec\n\nCurrently this specification is casual, as we gather feedback from implementors. A more rigorous\ne.g. BNF will follow.\n\n## General considerations\n\n**edn** elements, streams and files should be encoded using [UTF-8](http://en.wikipedia.org/wiki/UTF-8).\n\nElements are generally separated by whitespace. Whitespace, other than within strings, is not\notherwise significant, nor need redundant whitespace be preserved during transmissions. Commas `,`\nare also considered whitespace, other than within strings.\n\nThe delimiters `{ } ( ) [ ]` need not be separated from adjacent elements by whitespace.\n\n### # dispatch character\n\nTokens beginning with `#` are reserved. The character following `#` determines the behavior. The\ndispatches `#{` (sets), `#_` (discard), #alphabetic-char (tag) are defined below. `#` is not a\ndelimiter.\n\n## Built-in elements\n\n### nil\n\n`nil` represents nil, null or nothing. It should be read as an object with similar meaning on the\ntarget platform.\n\n### booleans\n\n`true` and `false` should be mapped to booleans.\n\nIf a platform has canonic values for true and false, it is a further semantic of booleans that all\ninstances of `true` yield that (identical) value, and similarly for `false`.\n\n### strings\n\nStrings are enclosed in `\"double quotes\"`. May span multiple lines. Standard C/Java escape\ncharacters `\\t, \\r, \\n, \\\\ and \\\"` are supported.\n\n### characters\n\nCharacters are preceded by a backslash: `\\c`, `\\newline`, `\\return`, `\\space` and `\\tab` yield the\ncorresponding characters. Unicode characters are represented with \\uNNNN as in Java. Backslash cannot be\nfollowed by whitespace.\n\n### symbols\n\nSymbols are used to represent identifiers, and should map to something other than strings, if\npossible.\n\nSymbols begin with a non-numeric character and can contain alphanumeric characters and `. * + ! - _ ?\n$ % \u0026 = \u003c \u003e`. If `-`, `+` or `.` are the first character, the second character (if any) must be\nnon-numeric. Additionally, `: #` are allowed as constituent characters in symbols other than as the\nfirst character.\n\n`/` has special meaning in symbols. It can be used once only in the middle of a symbol to separate\nthe _prefix_ (often a namespace) from the _name_, e.g. `my-namespace/foo`. `/` by itself is a legal\nsymbol, but otherwise neither the _prefix_ nor the _name_ part can be empty when the symbol\ncontains `/`.\n\nIf a symbol has a _prefix_ and `/`, the following _name_ component should follow the\nfirst-character restrictions for symbols as a whole. This is to avoid ambiguity in reading contexts\nwhere prefixes might be presumed as implicitly included namespaces and elided thereafter.\n\n### keywords\n\nKeywords are identifiers that typically designate themselves. They are semantically akin to\nenumeration values. Keywords follow the rules of symbols, except they can (and must) begin with `:`, e.g. `:fred` or `:my/fred`. If the target platform does not have a keyword type distinct\nfrom a symbol type, the same type can be used without conflict, since the mandatory leading `:` of\nkeywords is disallowed for symbols. Per the symbol rules above, :/ and :/anything are not legal keywords.\nA keyword cannot begin with ::\n\nIf the target platform supports some notion of interning, it is a further semantic of keywords that\nall instances of the same keyword yield the identical object.\n\n### integers\n\nIntegers consist of the digits `0` - `9`, optionally prefixed by `-` to indicate a negative number, or\n(redundantly) by `+`. No integer other than 0 may begin with 0. 64-bit (signed integer) precision is\nexpected. An integer can have the suffix `N` to indicate that arbitrary precision is desired. -0 is a\nvalid integer not distinct from 0.\n\n    integer\n      int\n      int N\n    digit\n      0-9\n    int\n      digit\n      1-9 digits\n      + digit\n      + 1-9 digits\n      - digit\n      - 1-9 digits\n\n### floating point numbers\n\n64-bit (double) precision is expected.\n\n    floating-point-number\n      int M\n      int frac\n      int exp\n      int frac exp\n    digit\n      0-9\n    int\n      digit\n      1-9 digits\n      + digit\n      + 1-9 digits\n      - digit\n      - 1-9 digits\n    frac\n      . digits\n    exp\n      ex digits\n    digits\n      digit\n      digit digits\n    ex\n      e\n      e+\n      e-\n      E\n      E+\n      E-\n\nIn addition, a floating-point number may have the suffix `M` to indicate that exact precision is\ndesired.\n\n### lists\n\nA list is a sequence of values. Lists are represented by zero or more elements enclosed in\nparentheses `()`. Note that lists can be heterogeneous.\n \n    (a b 42)\n\n### vectors\n\nA vector is a sequence of values that supports random access. Vectors are represented by zero or\nmore elements enclosed in square brackets `[]`. Note that vectors can be heterogeneous.\n\n    [a b 42]\n\n### maps\n\nA map is a collection of associations between keys and values. Maps are represented by zero or more\nkey and value pairs enclosed in curly braces `{}`. Each key should appear at most once. No\nsemantics should be associated with the order in which the pairs appear.\n\n    {:a 1, \"foo\" :bar, [1 2 3] four}\n\nNote that keys and values can be elements of any type. The use of commas above is optional, as they\nare parsed as whitespace.\n\n### sets\n\nA set is a collection of unique values. Sets are represented by zero or more elements enclosed in\ncurly braces preceded by `#` `#{}`. No semantics should be associated with the order in which the\nelements appear. Note that sets can be heterogeneous.\n\n    #{a b [1 2 3]}\n\n## tagged elements\n\n**edn** supports extensibility through a simple mechanism. `#` followed immediately by a symbol\nstarting with an alphabetic character indicates that _that symbol_ is a **_tag_**. A tag indicates\nthe semantic interpretation of _the following element_. It is envisioned that a reader\nimplementation will allow clients to register handlers for specific tags. Upon encountering a tag,\nthe reader will first read the next element (which may itself be or comprise other tagged elements),\nthen pass the result to the corresponding handler for further interpretation, and the result of the\nhandler will be the data value yielded by the tag + tagged element, i.e. reading a tag and tagged\nelement yields one value. This value is the value to be returned to the program and is not further\ninterpreted as **edn** data by the reader.\n\nThis process will bottom out on elements either understood or built-in. \n\nThus you can build new distinct readable elements out of (and only out of) other readable elements,\nkeeping extenders and extension consumers out of the text business.\n\nThe semantics of a tag, and the type and interpretation of the tagged element are defined by the\nsteward of the tag.\n\n    #myapp/Person {:first \"Fred\" :last \"Mertz\"}\n\nIf a reader encounters a tag for which no handler is registered, the implementation can either\nreport an error, call a designated 'unknown element' handler, or create a well-known generic\nrepresentation that contains both the tag and the tagged element, as it sees fit. Note that the\nnon-error strategies allow for readers which are capable of reading any and all **edn**, in spite\nof being unaware of the details of any extensions present.\n\n### rules for tags\n\nTag symbols without a prefix are reserved by **edn** for built-ins defined using the tag system. \n\nUser tags _**must**_ contain a prefix component, which must be owned by the user (e.g. trademark or\ndomain) or known unique in the communication context.\n\nA tag _may_ specify more than one format for the tagged element, e.g. both a string and a vector\nrepresentation.\n\nTags themselves are not elements. It is an error to have a tag without a corresponding tagged\nelement.\n\n## built-in tagged elements\n\n### #inst \"rfc-3339-format\"\n\nAn instant in time. The tagged element is a string in\n[RFC-3339](http://www.ietf.org/rfc/rfc3339.txt) format.\n\n`#inst \"1985-04-12T23:20:50.52Z\"`\n\n### #uuid \"f81d4fae-7dec-11d0-a765-00a0c91e6bf6\"\n\nA [UUID](http://en.wikipedia.org/wiki/Universally_unique_identifier). The tagged element is a\ncanonical UUID string representation.\n\n## comments\n\nIf a `;` character is encountered outside of a string, that character and all subsequent characters\nto the next newline should be ignored.\n\n## discard\n\n`#` followed immediately by `_` is the discard sequence, indicating that the next element (whether\nseparated from `#_` by whitespace or not) should be read and discarded. Note that the next element\nmust still be a readable element. A reader should not call user-supplied tag handlers during the\nprocessing of the element to be discarded.\n\n    [a b #_foo 42] =\u003e [a b 42]\n\nThe discard sequence is not an element. It is an error to have a discard sequence without a\nfollowing element.\n\n## equality\n\nSets and maps have requirements that their elements and keys respectively be unique, which requires\na mechanism for determining when 2 values are not unique (i.e. are equal).\n\nnil, booleans, strings, characters, and symbols are equal to values of the same type with the same\n**edn** representation.\n\nintegers and floating point numbers should be considered equal to values only of the same\nmagnitude, _type, and precision_. Comingling numeric types and precision in map/set key/elements,\nor constituents therein, is not advised.\n\nsequences (lists and vectors) are equal to other sequences whose count of elements is the same, and\nfor which each corresponding pair of elements (by ordinal) is equal.\n\nsets are equal if they have the same count of elements and, for every element in one set, an equal\nelement is in the other.\n\nmaps are equal if they have the same number of entries, and for every key/value entry in one map an\nequal key is present and mapped to an equal value in the other.\n\ntagged elements must define their own equality semantics. #uuid elements are equal if their canonic\nrepresentations are equal. #inst elements are equal if their representation strings designate the\nsame timestamp per [RFC-3339](http://www.ietf.org/rfc/rfc3339.txt).\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedn-format%2Fedn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fedn-format%2Fedn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedn-format%2Fedn/lists"}