Add symbol literal syntax with the same alias resolving behavior as auto-resolved keywords

Description

Rationale

When the namespace component of an auto-resolving keyword literal refers to an undeclared alias, the reader produces an error, like so:

For symbols, however, no such syntax exists. This is a common source of errors with functions like clojure.spec.test.alpha/instrument which accept qualified symbols of var names as arguments. Currently, the go-to notation for such symbol literals is syntax quote which of course accepts any namespace. Now, when one accidentally refers to an alias in one of those symbolic arguments which hasn't been declared in the current namespace (e.g. when transplanting some code from one namespace to another), it would be very useful to have the same error behavior as with auto-resolving keywords. To stick with the instrument example, one would end up calling potentially expensive real functions instead of the mocks which could easily go unnoticed.

Suggested syntax

This is a bit tricky. The first thing that comes to mind is double backtick, as in ``foo/bar, but that already has meaning and is likely to already be used in existing macros. I guess %foo/bar could work, though there is of course no guarantee that this isn't already in use in actual namespace names, too.

Status

As you can tell, I haven't done an extensive survey of possible syntax options, yet, nor have I started working on a patch. Just wanted to solicit opinions on the issue to see if it's worth pursuing any further.

Environment

None

Activity

Show:
Alex Miller
March 20, 2019, 12:44 AM

While I understand your use case, this would be a big syntax addition and I think it’s unlikely. I’m going to Backlog this for now.

import
March 20, 2019, 6:51 AM

Comment made by: dergutemoritz

Agreed, it's a pretty invasive change probably not worth the trouble. FWIW, in the meantime I figured that the same can be achieved via a tagged literal. In case anyone is looking for a solution, you could have a function like this:

Register it e.g. for the sym tag by putting it in data_readers.clj at the root of your classpath:

And now you can use it to the same effect as ::foo/bar for keywords like this:

import
March 20, 2019, 7:06 AM

Comment made by: dergutemoritz

In case of the :replace argument from the instrument example, there's another solution that already works. Just use auto-resolved map namespaces with syntax quote like this:

The catch is of course that you need to unquote values now. Note that the syntax quote needs to apply to the whole expression - if it goes in front of the key, the map's namespace won't apply to it because it will already be namespaced by the syntax quote. Actually, one could expect

to also namespace the symbol key but that's not happening. Maybe it only accidentally works with syntax quote after all...

Assignee

Unassigned

Reporter

import

Labels

None

Approval

None

Patch

None

Fix versions

Affects versions

Priority

Minor