dedbox
2017-12-13 16:07:18

(sorry, fell asleep mid conversation)


dedbox
2017-12-13 16:08:54

There are some fundamental differences between ip and authority.


dedbox
2017-12-13 16:09:35

An IP is a giant number encoded as bytes.


dedbox
2017-12-13 16:10:52

An authority is a composition of other types.


dedbox
2017-12-13 16:12:00

If we think of them as data containers, direct syntax can make sense for either.


dedbox
2017-12-13 16:13:46

If we want them to interact with each other or the environment, we may need to make some design decisions.


dedbox
2017-12-13 16:14:48

At this point, using ips and authorities as containers is sufficient for axon.


dedbox
2017-12-13 16:15:24

And the simple syntax feels so clean.


dedbox
2017-12-13 16:20:14

For scheme-specific stuff, we have plenty of room in the URI API that needs filling out


dedbox
2017-12-13 16:49:16

For example, the scheme part of a URI is just a string. URI users can lookup scheme-specific info from a “database” keyed by the scheme name.


dedbox
2017-12-13 16:50:31

#uri"<http://whatever.com:9876/abc?def#ghi>"


dedbox
2017-12-13 16:53:10

the http:// tell us we’re doing a hierarchical parse, with authority = host + optional port. With the way RFCs are written to cascade, that’s a huge chunk of use cases right there, so we might want to extract a generic “hierarhical host+port” authority parser.


dedbox
2017-12-13 16:55:12

Poking around, it’s a lot harder to see patterns among non-hierarchical URIs.


dedbox
2017-12-13 16:55:19

<mailto:dedbox@gmail.com>


dedbox
2017-12-13 16:55:33

tel:8885551212


dedbox
2017-12-13 16:59:01

Things will get interesting if we want to reject mailto:8885551212 or tel:dedbox@gmail.com as syntax errors.


dedbox
2017-12-13 17:01:25

In either case, we’re looking at serious meta-programming.


dedbox
2017-12-13 17:01:32

My favorite kind, actually.


dedbox
2017-12-13 17:04:20

I think the clean feeling of my current syntax comes from the fact that URIs and hostnames really are just strings to me, so I don’t care what net2 does with them. At least, not until I do, at which point I only want certain things, like hostname or port.


dedbox
2017-12-13 17:08:23

So net2/data gives me a convenient way to munge URI data without resorting to string processing.


dedbox
2017-12-13 18:09:04

Concretely, #authority"192.168.1.2:34" is equivalent to (authority #ip4"192.168.1.2" 34)


notjack
2017-12-13 18:38:10

I can see the use for that. I’m much less sure about how to get it to work right though so I’d rather not commit to doing it in v1


notjack
2017-12-13 18:39:25

also do you think both ip address versions ought to be handled with the same tag?


notjack
2017-12-13 19:22:38

@dedbox Wait. Isn’t the “tag” itself doing the exact same thing as a URI scheme?

  • #uri"<http://whatever.com:9876/abc?def#ghi>" => #<http://whatever.com:9876/abc?def#ghi>
  • #dns"<http://example.com\|example.com>" => #dns:<http://example.com\|example.com>

notjack
2017-12-13 19:23:37

There’s an RFC for representing DNS records as URIs so this isn’t totally without precedent: https://tools.ietf.org/html/rfc4501


notjack
2017-12-13 19:24:43

It also looks remarkably similar to Clojure’s Extensible Data Notation, see https://github.com/edn-format/edn and https://clojure.org/reference/reader#tagged_literals


notjack
2017-12-13 19:25:13

(thanks to @samth for triggering this thought in a github issue about #hash() literals)


notjack
2017-12-13 19:25:58

dedbox
2017-12-13 20:07:05

heh, I read the DNS scheme spec out of curiosity. It wasn’t quite what I expected.


dedbox
2017-12-13 20:09:06

According to RFC 4501, >A DNS URI designates a DNS resource record set, referenced by domain name, class, type, and, optionally, the authority.


dedbox
2017-12-13 20:09:30

> dnsurl = “dns:” [ "//" dnsauthority "/" ] dnsname ["?" dnsquery]


dedbox
2017-12-13 20:11:22

Kinda confusing that dns:<http://example.com\|example.com> and <dns://example.com/>... mean such different things


dedbox
2017-12-13 20:14:39

re: edn tagged elements, this is more or less what I had in mind


dedbox
2017-12-13 20:18:05

I imagine net2 would come with some basics (e.g., URIs and their parts), maybe with an extensibility mechanism.


dedbox
2017-12-13 20:18:52

Then protocol implementers can provide their own tagged elements.


dedbox
2017-12-13 20:20:03

@notjack Back to the present, what are you willing to accept for now?


dedbox
2017-12-13 20:20:45

~I am comfortable with hairy syntax-ey stuff.~ I can code up anything we might want to try.


notjack
2017-12-13 20:29:39

I think only providing string-&gt;ip and string-&gt;dns is best for v1 with explicit use of an authority constructor required for adding port info. A GitHub issue for exploratory design of literal syntaxes would be good though.


dedbox
2017-12-13 20:33:40

> also do you think both ip address versions ought to be handled with the same tag?


dedbox
2017-12-13 20:33:44

Almost missed that.


dedbox
2017-12-13 20:35:12

Having two distinct structs makes the library simpler by eliminating some structural checks. It also adds complexity by requiring similar checks elsewhere.


dedbox
2017-12-13 20:36:55

It would be about as easy (as what I havenow) to use a single ip struct and provide ip4? and ip6? predicates.


dedbox
2017-12-13 20:37:20

Except then every IP would occupy at least 16 bytes.


dedbox
2017-12-13 20:38:22

So maybe keeping them separate gives us a bigger win (in memory) than unifying them (in cycles).


dedbox
2017-12-13 20:40:56

For the API, unifying them simplifies the syntax (one less constructor) but complicates the semantics (more run-time “type” checking, which might not matter down the road in TR).


dedbox
2017-12-13 20:42:18

I think keeping them separate is the safer approach.


notjack
2017-12-13 20:55:36

I agree


notjack
2017-12-13 21:05:58

There’s a notion of generic “ip literals” in the URI 3xxx spec that might be worth using in the API names


notjack
2017-12-13 21:09:00

string-&gt;ip4, string-&gt;ip6, string-&gt;ip-literal


dedbox
2017-12-13 21:12:40

Cool. That’ll drop right in.


dedbox
2017-12-13 21:13:15

oh, wait.


dedbox
2017-12-13 21:13:49

An IP literal is just an IPv6address or IPvFuture wrapped in square brackets.


dedbox
2017-12-13 21:14:03

already doing that


dedbox
2017-12-13 21:15:07

Maybe you meant host, which is an ip or reg-name literal.


dedbox
2017-12-13 21:15:58

also doing that, actually


notjack
2017-12-13 21:17:10

Hmm. Maybe just string-&gt;ip which does either v4 or literal


dedbox
2017-12-13 21:18:13

The authority constructor needs to do string-&gt;host, or equivalently string-&gt;ip-or-reg-name.


dedbox
2017-12-13 21:19:06

which I guess in practice means string-&gt;ip-or-dns


notjack
2017-12-13 21:20:19

I think the authority constructor should require non-string (already parsed) arguments


notjack
2017-12-13 21:20:32

because schemes may define arbitrary kinds of authorities


dedbox
2017-12-13 21:22:40

Ok, then whatever uses the authority constructor will need to do that.


dedbox
2017-12-13 21:23:18

I guess my point is that it’s easy and I’m already doing it, so we can cal it what we want and put it wherever.


notjack
2017-12-13 21:23:56

a string-&gt;authority function maybe?


dedbox
2017-12-13 21:24:03

yes


dedbox
2017-12-13 21:24:20

I’m updating the code now, to try it out


dedbox
2017-12-13 21:24:54

I just undo the constructor trickery and rename the old constructor string-&gt;foo


dedbox
2017-12-13 21:25:07

The foo-&gt;string functions are already there


notjack
2017-12-13 21:36:47

:thumbsup:


notjack
2017-12-13 21:36:53

thanks for filing the literal syntax issue btw


notjack
2017-12-13 21:47:04

I just found https://tools.ietf.org/html/rfc4367 which I think is very relevant to the dns struct definition


dedbox
2017-12-13 22:08:15

then I’ll read it


dedbox
2017-12-13 22:08:42

looks like I need host-&gt;string in axon.


dedbox
2017-12-13 22:09:10

because I don’t always know or care what kind of host I’m working with.


dedbox
2017-12-13 22:09:48

No big deal. I can just extract the code from authority-&gt;string


dedbox
2017-12-13 22:10:23

But replacing ~a wit foo-&gt;string is not always straight forward.


dedbox
2017-12-13 22:10:53

Now I have to choose which printer to use.


dedbox
2017-12-13 22:11:59

It looks like this right now: (define (host-&gt;string host) (cond [(ip4? host) (ip4-&gt;string host)] [(ip6? host) (ip6-&gt;string host)] [(dns? host) (dns-&gt;string host)]))


notjack
2017-12-13 22:12:05

maybe a net-host? predicate matching ip4?, ip6?, and dns? values?


notjack
2017-12-13 22:12:45

this also makes me think about ditching reg-name as a super-struct and having a host super-struct that ip, dns, virtual addresses, and whatever else all inherit from


dedbox
2017-12-13 22:12:49

not extensible


dedbox
2017-12-13 22:13:16

sorry, was still talking about foo-&gt;string


dedbox
2017-12-13 22:21:27

host super-struct is not far from reg-name setup we have now, and it has other benefits


dedbox
2017-12-13 22:22:51

Like keeping ip4 and ip6 types distinct or unified as needed.


notjack
2017-12-13 22:23:46

yes, and a generic parser would require some sort of generic (string-reg-name "some-string") for parsing authorities of uris with unknown schemes - making host the abstract super-struct would free the struct reg-name to not be a supertype of any kind and be just a normal host subtype like any other except it contains any random string for some unknown non-ip host


dedbox
2017-12-13 22:24:37

Just rename the current reg-name to host and make everything else a sub-struct.


notjack
2017-12-13 22:25:15

yup


notjack
2017-12-13 22:25:35

but when a generic string-&gt;uri form is added it needs a sub-struct of host to use for authorities it doesn’t recognize


notjack
2017-12-13 22:26:07

it would just stick the unparsed string it didn’t recognize into that


dedbox
2017-12-13 23:01:54

Ok. I’m using a null-authority instance with ~all~ both fields #f right now. It could be an instance of the “unknown” host sub-type on the empty string instead, and not have that extra #f dangling.


notjack
2017-12-13 23:02:26

hmm, I think there is no such thing as an authority with a null host


notjack
2017-12-13 23:02:51

as in, the authority if present always has a host and optionally has a port, but within a URI the entire authority may be absent


notjack
2017-12-13 23:03:36
uri-authority : Uri -&gt; Maybe Authority
authority-host : Authority -&gt; Host
authority-port : Authority -&gt; Maybe Port

notjack
2017-12-13 23:04:05

because what would a URI with no host but a present port mean?


notjack
2017-12-13 23:04:10

http::80/foo?


dedbox
2017-12-13 23:04:29

But the host part could be anything.


dedbox
2017-12-13 23:05:10

fie:///...


notjack
2017-12-13 23:05:23

I think it can only be anything except the empty string - the entire authority can be empty, but that’s different from the authority being nonempty and the host being empty


dedbox
2017-12-13 23:05:55

The authority part is empty. In one of the many RFCs I’ve read recently, it was pointed out.


notjack
2017-12-13 23:06:11

file:/// is empty authority - empty host in nonempty authority would be something like file://:80/ I think


dedbox
2017-12-13 23:07:01

Ohh, ok


dedbox
2017-12-13 23:08:43

We’ll, I really care about empty authority, and the host struct design is a better model than what we have now.


notjack
2017-12-13 23:09:11

in that case I think places where you do accept an authority you could also accept #f to represent empty authority, instead of authority with two #f fields


notjack
2017-12-13 23:10:18

it should be impossible for a net2 client to construct an authority struct where the host is empty and the port is present


notjack
2017-12-13 23:10:54

that’s a useful invariant


dedbox
2017-12-13 23:19:00

Ok that makes sense.