OK that’s a really interesting question: if you’re interpreting a text without knowing what it’s about, having type information embedded in it could help clarify the writer’s intent? That seems reasonable. Have you done this?
(
{
:name "Fred"
:age 35
}
{
:name 37
:age "Wilma"
}
)
There's a semantic error here; the name and age fields have been
swapped in the second element of the list. At some point, somebody
has to check whether :name is a string and :age is a number. If your
application is going to do that anyway, why do syntax typing?
You might as well just try to construct a number from "Wilma" at the
point where you know you need a number.Obviously I have an opinion here, but I'm putting it out there in the hope of being contradicted. The whole world seems to run on JSON, and I'm struggling to understand how syntax typing helps with JSON document validation rather than needlessly complicating the syntax.
you can run it locally with `make bench bench-clj bench-wasm`
Let me know if I can do anything to help you with support in jank.
As a side note, I'm curious how much AI was used in the creation of edn.c. These days, I like to get a measure of that for every library I use.
This is a `map`, which bears semblence with a Json object. The following might look like an incorrect paylood, but will actually parse as valid EDN:
{:a 1, "foo" :bar, [1 2 3] four}
// Note that keys and values can be elements of any type.
// The use of commas above is optional, as they are parsed as whitespace.
If one wants to exchange complex data structures, Aterm is also an option: https://homepages.cwi.nl/~daybuild/daily-books/technology/at...Some projects in Haskell use Aterms, as it is suitable for exchanging Sum and Product types.
If you worked in exclusively static typed languages it takes a while to grasp how convenient this is when you're mixing data from different sources.
(html
(head
(title "Hello!"))
(body
(div
(p
"This is an example of a hyperlink: "
(a "Example" :href "https://example.org/")))))tl;dr first element of the vector is a tag, second is a map of attributes test are children nodes:
[:h1 {:font-size "2em" :font-weight bold} "General Kenobi, you are a bold one"]
https://github.com/clj-commons/hickory
i feel hiccup indexed based magic is a common design pattern you see in early Clojure and its less common now (id say hiccup is the exception that lives on)
I think ASN.1 (and ASN.1X which is I added a few additional types such as key/value list and TRON string) is better. (I also made up a text-based ASN.1 format called TER which is intended to be converted to the binary DER format. It is also intended that extensions and subsets of TER can be made for specific applications if needed.) (I also wrote a DER decoder/encoder library in C, and programs that use that library, to convert TER to DER and to convert JSON to DER.)
ASN.1 (and ASN.1X) has many similar types than EDN, and a comparison can be made:
- Null (called "nil" in EDN) and booleans are available in ASN.1.
- Strings in ASN.1 are fortunately not limited to Unicode; you can also use ISO 2022, as well as octet strings and bit strings. However, there is no "single character" type.
- ASN.1 does have a Enumerated type, although the enumeration is made as numbers rather than as names. The EDN "keywords" type seems to be intended for enumerations.
- The integer and floating point types in ASN.1 are already arbitrary precision. If a reader requires a limited precision (e.g. 64-bits), it is easy to detect if it is out of range and result in an error condition.
- ASN.1 does not have a separate "list" and "vector" type, but does have a "set" type and a "sequence" type. A key/value list ("map") type is a nonstandard type in ASN.1X, but standard ASN.1 does not have a key/value list type.
- ASN.1 does have tagging, although its working is difference from EDN. ASN.1 does already have a date/time type though, so this extension is not needed. Extensions are possible by application types and private types, as well as by other methods such as External, Embedded PDV, and the nonstandard
- The rational number type (in edn.c but the main EDN specification does not seems to mention it), is not a standard type in ASN.1 but ASN.1X does have such a type.
(Some people complain that ASN.1 is complicated; this is not wrong, but you will only need to implement the parts that you will use (which is simpler when using DER rather than BER; I think BER is not very good and DER is much better), which ends up making it simpler while also capable of doing the things that would be desirable.)
(But, EDN does solve some of the problems with JSON, such as comments and a proper integer type.)
The best part of EDN that it is extendable :)
#binary/base64 "SGVsbG8sIHp6bzM4Y29tcHV0ZXIhIEhvdyBhcmUgeW91IGRvaW5nPw=="
This is a tagged literal that can be read by provided (if provided) custom reader during reading of the document. The result could be any type you want.
Also, if there is not a binary file format for the data then you will need to always convert to/from base64 when working with this file whether or not you should need to.
Furthermore, this does not work very well when you want to deal with character sets rather than binary data, since (as far as I can tell from the specification) the input will still need to be UTF-8 and follow the EDN syntax of an existing type.
From what I can understand from the specification, the EDN decoder will still need to run and cannot be streamed if the official specification is used (which can make it inefficient), although it would probably be possible to make an implementation that can do this with streaming instead (but I don't know if the existing one does).
So, the extensibility is still restricted. (In my opinion, ASN.1 (and ASN.1X) does it better.)
{:pi 3.141_592_653_589
:c 299_792_458
:hex 0xDE_AD_BE_EF
:tb """
#!/usr/bin/env bb
(require '[babashka.http-client :as http])
(defn get-url [url]
(println "Downloading url:" url)
(http/get url))
"""}Call it symbol, if it's not identifiable
more than that: in this reader implementation nil, true, false are also valid identifiers with special handling to turn them into nil and bool.
I encourage you to reread original specification and then continue after "this insanity" :)