Display more descriptive error message when trying to use reader conditionals in a non-cljc file

Description

I spent a few puzzled minutes trying to understand the following message from the Clojure compiler:

Eventually I realised it was because I was trying to use reader conditionals in a .clj file that I hadn't renamed to cljc. I think it would be really helpful for people working in mixed clj and cljc codebases to have this error message extended to something like:

"Conditional read not allowed because file does not have extension .cljc"

Environment

None

Activity

Show:
Alex Miller
May 20, 2015, 5:45 AM

The reader doesn't know this - it can be called in multiple ways (from repl, via clojure.core/read, via clojure.core/read-string, load/compile .cljc, load/compile .clj) so that description would actually be wrong in some of those. It seems like you're getting a pretty good error message already - it told you the problem and gave you the file name.

The message could be tweaked to something like "Reader conditionals not allowed in this context" which might give you a better clue.

Daniel Compton
May 20, 2015, 9:12 PM

Perhaps I'm not understanding how the reader determines whether reader conditionals are allowed or not, but those would all seem to have different reasons for not being allowed and would be caught by different checks. Each of these checks could give a more specific warning explaining why the read wasn't allowed?

Counteracting my point, it looks like there is only one place where this exception is thrown - https://github.com/clojure/clojure/blob/7b9c61d83304ff9d5f9feddecf23e620c0b33c6e/src/jvm/clojure/lang/LispReader.java#L1406. I'm not sure if this could be extended to give more details in different error cases or if that information isn't available at that point?

Alex Miller
May 20, 2015, 9:36 PM

The reader is invoked with an options map which will (or will not) have {:read-cond :allow} or {:read-cond reserve}. That's the only info the reader has - if either of those is set and a reader conditional is encountered, it throws.

The compiler decides how to initialize these options when it's calling the reader. Users of read and read-string similarly decide which options are allowed when they call it. It would be possible to pass more info into the reader or to catch and rethrow in the compiler where more context is known, but both of those complicate the code for what is already a decent error imho.

Daniel Compton
May 20, 2015, 10:03 PM

I agree it is a reasonable error message, I guess we can wait and see how other people find it once 1.7 is released. If it turns out to be an issue for lots of other people then we could revisit this then?

import
October 6, 2016, 4:09 PM

Comment made by: mars0i

I encountered the problem with using reader conditionals in a .clj file. I would have had no idea of how to fix the error meant except for Daniel Compton's blog post about it. I understand that it's not just a filename issue, and that there can be other sources of this error, but when it is a filename issue, it's very mysterious, and this seems like an easy mistake to make. A contributing context is that Clojurescript macros can be defined in a .clj file, so it can be natural to use that extension as a reminder about when the macros will be compiled.

I do think that something like "Reader conditionals not allowed ..." would be a lot easier to understand than "Conditional read not allowed". That would at least make it obvious that it's the reader conditional that's causing the problem. Once you know that this is what "conditional read" means, it's obvious, but "conditional read" is not a common phrase in the Clojure world, afaik, and I wondered why it didn't say "reader conditional" if that's what the message was about.

(An option would be to add a comment in the error string stating that the cause might be reader conditionals used outside of a .cljc file. Not sure if you want to go down that road of "might be"/"maybe" in error messages, since that kind of thing could get out of hand and lead to long error messages. However, this sort of thing has been done elsewhere, and it might be very helpful in this case; mistakenly using .clj with a reader conditional seems like something that would occur often.)

Assignee

Unassigned

Reporter

Daniel Compton

Labels

Approval

None

Patch

None

Affects versions

Priority

Minor
Configure