On 26 August 2016 at 10:31, Colin Fleming <colin.mailingl...@gmail.com>
wrote:

> I agree that tidied up the error messages are much more understandable.
> Replacing things like "path" with a description of what it means goes a
> long way. My main issue with the original error which persists in your
> version is that the failing predicate really doesn't help much identifying
> the problem. However Leon's investigations hopefully will help to make that
> better by more precisely identifying the failing predicate.
>

Yes the failing predicate isn't always very enlightening, and something
like Leon's suggestion seems to match my intuitions about being more
accurate, more frequently - though I'll leave judgement on that to people
who know this stuff much better than I.


> I'd envisioned the source text for a particular top-level form only being
> held for as long as required to eval or compile the form, not being stored
> permanently in metadata.
>

Yes, this occurred to me only after reading your response to Alex.  That
could be pretty cool, but might require extra specialisation for the macro
case.


> But I'd have to go and look at the code to see if that's feasible or not.
> AOTing would not be a problem since the macroexpansion errors would be
> found when the form was AOTed, those errors would never occur at runtime.
>

Sounds feasible then...

Thanks for the kind words about Cursive too, one of my main goals is to
> make Clojure more approachable (hence the obsession with error messages),
> so I'm glad it's helped your co-workers! And you never know, maybe you'll
> like it enough one day to switch :-)
>

Well the biggest barrier to me trying to use it more are the lack of Emacs
& CIDER & Emacs paredit style keybindings.  I'm not sure if you can easily
share those configs with intellij; but if there was a config that had all
that together I'd probably be able to last more than 5 minutes without
getting frustrated... A discussion for another thread perhaps...

R.



>
> On 26 August 2016 at 21:15, Rick Moynihan <rick.moyni...@gmail.com> wrote:
>
>> On 26 August 2016 at 03:11, Colin Fleming <colin.mailingl...@gmail.com>
>> wrote:
>>
>>> Hi Rick,
>>>
>>> That looks really excellent, and is a huge improvement. Particularly in
>>> combination with Leon's proposed change which more precisely identifies the
>>> likely failing part of the grammar, this looks like a big win for not much
>>> extra effort.
>>>
>>
>> Well it was really just 5-10 minutes work.  I think it shows though that
>> specs errors are actually better than a lot of people are giving them
>> credit for.  Once I'd tidied it up a bit it surprised me.
>>
>>
>>> One thing that I think would help a lot would be if it were possible to
>>> show the actual text from the failing expression rather than pretty
>>> printing a seq representation of it. This would mean modifying the reader
>>> such that it either caches the program text from each top-level form as it
>>> reads it, or perhaps re-reading the file on an error. This means the
>>> relevant code is likely to look more familiar to the user, and also avoids
>>> any need to pretty print. Pretty printing is likely to be complicated since
>>> it normally works top-down, and uses the type of each form to decide how to
>>> lay its sub-parts out. If you're only pretty-printing a fragment from
>>> within, say, a large ns form, pprint is unlikely to format it as the user
>>> would expect.
>>>
>>
>> Yes, as I was re-rendering the error message it did occur to me that you
>> could do lots more to make it even nicer.  Capturing the source text is
>> certainly one, though mightn't there be a risk of using a large amount of
>> memory to store those metadata strings, especially if they're nested,
>> overlapping sexps.
>>
>> Re-reading the file on error would presumably only work if the file was
>> available, if it was only aot'd you'd have to either have captured the
>> source text at macro expansion time (as mentioned above) or try to lookup
>> the source for an even better error - and if it's not found fallback to a
>> pretty-pinting of the form.
>>
>> I didn't want to go too far down the road with the example, as I wanted
>> to show how much better the message could be with just a modest amount of
>> work.  The main ideas of the proposal are also independent and don't rely
>> too much on each other.
>>
>> I'm curious whether the core team plan for the formatting of these
>> strings to be a contract; or whether after 1.9.0 is released if they could
>> be flagged as experimental - with further improvements to the rendering
>> being pushed into future clojure releases?
>>
>> R.
>>
>> p.s. Colin, just wanted to say a massive thanks for Cursive!  I'm an
>> Emacs Cider user myself, but it's really helped many members of our team,
>> and I've been so impressed with the progress, that I even asked my boss to
>> buy me a copy... I think it'll still take quite a lot to get me off
>> Emacs/Cider; but you might well make it! :-)
>>
>>
>>> Cheers,
>>> Colin
>>>
>>> On 26 August 2016 at 12:59, Rick Moynihan <rick.moyni...@gmail.com>
>>> wrote:
>>>
>>>> I think one obvious area that specs error messages could be improved is
>>>> with some basic formatting and cosmetic changes. If spec presented errors
>>>> not as a wall of text and syntax but with some simple formatting it would
>>>> make a big difference to legibility.
>>>>
>>>> As a starter for 10, why could we not render the messages at a REPL
>>>> more like this?  (Note this is basically Brian's error - re-rendered):
>>>>
>>>> user=> (ns such.sequences (require ,,,,))
>>>>
>>>> CompilerException clojure.lang.SpecException:
>>>>
>>>> Call to clojure.core/ns did not conform to fdef [:args] spec
>>>>
>>>> There was unexpected extra input in: [2]
>>>>
>>>> with value: (,,, (require [such.vars :as var]
>>>>                                      [such.immigration :as immigrate])
>>>>                        (require midje.checking.checkers.defining
>>>>                                     midje.checking.checkers.chatty
>>>>                                     midje.checking.checkers.simple
>>>>                                     midje.checking.checkers.combining
>>>>                                     midje.checking.checkers.collec
>>>> tion))
>>>>
>>>> Input failed spec predicate: (cat :attr-map (? map?)
>>>>                                                    :clauses
>>>> :clojure.core.specs/ns-clauses)
>>>>
>>>> When compiling: (such/sequences.clj:1:1)
>>>>
>>>> user=>
>>>>
>>>> Some things to point out:
>>>>
>>>> 1. Provide some extra context by subclassing IllegalArgumentException
>>>> as SpecException.  This may also help separate SpecException's from other
>>>> IllegalArgumentExceptions too, and help tools do something special on a
>>>> SpecException.
>>>>
>>>> 2. Use of new lines to break up and separate text blocks.
>>>>
>>>> 3. State that it's an fdef spec, and it was the [:args] bit of that
>>>> spec that failed.  By stating them together we implicitly associate [:args]
>>>> with fdef.  Note I'm assuming we can also capture that fdef defined this
>>>> spec.
>>>>
>>>> 4. It's a bit unclear what "Extra input" means... so clarify that it
>>>> was unexpected.  Provide the path [2] as before.
>>>>
>>>> 5. State the failing value and pretty print it.  Note that we also
>>>> elide the other passing parameters with a ,,,,
>>>>
>>>> 6. As before state the predicate that identified the failure in a
>>>> humanised manner and the location of the failing form.
>>>>
>>>> I'm not suggesting these are necessarily good ideas, and I appreciate
>>>> I've not considered all of the other cases you might need to, but it seems
>>>> that something like the above would be a dramatic if entirely cosmetic
>>>> improvement.  It would be a shame if clojure.core made no attempt to
>>>> humanise the display of these messages and left it entirely up to the
>>>> community.
>>>>
>>>> Thoughts?
>>>>
>>>> R.
>>>>
>>>>
>>>> On 20 August 2016 at 15:03, Alex Miller <a...@puredanger.com> wrote:
>>>>
>>>>>
>>>>>
>>>>> On Saturday, August 20, 2016 at 5:17:59 AM UTC-5, Brian Marick wrote:
>>>>>>
>>>>>> Yesterday, a bug was filed against Suchwow under 1.9alpha11. It turns
>>>>>> out to have been a use of `ns …(require…` instead of `(ns …(:require`. 
>>>>>> Not
>>>>>> in Suchwow, but in Midje. Unfortunately, the Suchwow file the bug report
>>>>>> pointed at *also* had that typo - apparently I am prone to it - so adding
>>>>>> the colon to the require there didn’t make the problem go away.
>>>>>>
>>>>>> That caused me to lose my temper and make a fool of myself, which is
>>>>>> neither here nor there, except that I apologize to @puredanger.
>>>>>>
>>>>>> I have two suggestions, though:
>>>>>>
>>>>>> 1. It has long been the case that Clojure allowed `(ns (require…)`
>>>>>> even though that’s strictly incorrect. I suggest that, for backwards
>>>>>> compatibility, it be allowed going forward. That is, I think it does no
>>>>>> harm for a correct `ns` statement to allow symbols as well as keywords.
>>>>>> That wrong code in Midje has been there since Clojure 1.2.
>>>>>>
>>>>>
>>>>> We discussed this before releasing the specs and decided to start on
>>>>> the strict side. That said, this is still an alpha and there is plenty of
>>>>> time to change our minds prior to official release of 1.9 if that ends up
>>>>> being a catastrophic decision.
>>>>>
>>>>>
>>>>>>
>>>>>> 2. The following is not a good error message:
>>>>>>
>>>>>> Exception in thread "main" java.lang.IllegalArgumentException: Call
>>>>>> to clojure.core/ns did not conform to spec:
>>>>>> In: [2] val: ((require [such.vars :as var] [such.immigration :as
>>>>>> immigrate]) (require midje.checking.checkers.defining
>>>>>> midje.checking.checkers.chatty midje.checking.checkers.simple
>>>>>> midje.checking.checkers.combining midje.checking.checkers.collection))
>>>>>> fails at: [:args] predicate: (cat :attr-map (? map?) :clauses
>>>>>> :clojure.core.specs/ns-clauses),  Extra input
>>>>>>
>>>>>
>>>>> You left out this next important line too since it points you to
>>>>> exactly the file and line where the error occurs:
>>>>>
>>>>> , compiling:(such/sequences.clj:1:1)
>>>>>
>>>>> spec produces very detailed error messages driven by the specs and the
>>>>> value being validated. I admit that in some cases the output from a spec
>>>>> error (particularly for complicated syntaxes where there are wide
>>>>> alternative fan-outs) is daunting. However, spec error messages are going
>>>>> to be increasingly common for all of us to see and understand and I think
>>>>> it is worth taking the time to slow down and actually read them.
>>>>>
>>>>> > Call to clojure.core/ns did not conform to spec:
>>>>>               ^^^^^^^^^^^^^^ <- macro that was passed invalid values
>>>>> > In: [2]
>>>>>         ^^^ <- the data path in the :args passed to the macro, here,
>>>>> the 2th element is the require clause (ns = 0, such.sequences = 1)
>>>>>
>>>>> > val: ((require [such.vars :as var] ...)
>>>>>          ^^ <- the remaining part of the value that did not match (it
>>>>> has already matched or "consumed" the first two elements successfully)
>>>>>
>>>>> > fails at: [:args]
>>>>>                ^^^^^^ <- the path in the ns fdef spec to the failure
>>>>> point
>>>>>
>>>>> > predicate: (cat :attr-map (? map?) :clauses
>>>>> :clojure.core.specs/ns-clauses),
>>>>>                     ^^^etc -> the remaining part of the spec it was
>>>>> trying to match
>>>>>
>>>>> > Extra input
>>>>>   specs way of saying that it found something (the val above) but it
>>>>> wasn't what the spec expected next
>>>>>
>>>>>
>>>>> I'm not trying to pretend this is as easy to digest as an error
>>>>> message that would be produced by hand-written validation and error code,
>>>>> but it's also notoriously difficult to cover all possible cases (which is
>>>>> why the Clojure DSLs have so many error gaps despite having a lot of that
>>>>> code). We are looking to decrease the amount of custom error detection and
>>>>> reporting, so anything we do has to be something we can do generically.
>>>>>
>>>>> For the specific case of macroexpanded error reporting, I think there
>>>>> *are* more things we can do here (generically) that will improve
>>>>> readability. We *know* we are in the context of checking an fdef spec on a
>>>>> macro, so some of the ":args" stuff is maybe not necessary. Having the val
>>>>> and predicate for a s/cat forwarded to the point of mismatch is both great
>>>>> (as it's specific) but also confusing (because parts of both the input and
>>>>> the cat spec) are missing which removes important context. I think there
>>>>> are ways to indicate that's happening better. Earlier versions of this 
>>>>> also
>>>>> reported the full args and we ended up removing that because in many cases
>>>>> it feels redundant (or is potentially large). Maybe there is some 
>>>>> heuristic
>>>>> we could follow on when that would help.
>>>>>
>>>>>
>>>>>> - It would be better to say “`require` should be a keyword, not a
>>>>>> symbol” than "fails at: [:args] predicate: (cat :attr-map (? map?) 
>>>>>> :clauses
>>>>>> :clojure.core.specs/ns-clauses),  Extra input”
>>>>>>
>>>>>> - Suggest Clojure.spec error messages follow the “inverted pyramid”
>>>>>> structure of news reports: https://en.wikipedia.
>>>>>> org/wiki/Inverted_pyramid That would mean the text message about the
>>>>>> error would come first, the spec second, and the wrong expression last.
>>>>>>
>>>>>> - It would be better to name the namespace that has the problem.
>>>>>>
>>>>>
>>>>> As mentioned above, the next line that you omitted points to the file
>>>>> and line with the problem (I went to some trouble to ensure that was
>>>>> reported properly from the point of use).
>>>>>
>>>>>
>>>>>> - The stack trace adds nothing to the error. If anything, it makes it
>>>>>> less understandable, as the sheer amount of text is offputting.
>>>>>>
>>>>>
>>>>> I agree, but this is to some degree an orthogonal issue. Tools
>>>>> (including the base REPL) choose what to do when they receive an exception
>>>>> from the compiler.  I would like to think more carefully about what the
>>>>> compiler is producing (informationally) and also how tools should be
>>>>> expected to handle these errors. Certainly in cases like this, the stack
>>>>> trace is unnecessary and that's true of many compiler errors. That is a
>>>>> fixable problem and I am interested in making improvements in this area
>>>>> still in 1.9.
>>>>>
>>>>>
>>>>>> My https://github.com/marick/structural-typing does (a small) part
>>>>>> of what clojure.spec does. I went to a lot of effort to get it to produce
>>>>>> good error messages, and it turned out OK. I doubt it would be applicable
>>>>>> to clojure.spec, but I’d be happy to sign over any code that could be of
>>>>>> use.
>>>>>>
>>>>>
>>>>> Thanks, I doubt there's much we could use directly.
>>>>>
>>>>>
>>>>>> It’s unfortunate that reporting errors is so much harder than
>>>>>> detecting them.
>>>>>>
>>>>>
>>>>> Indeed. Unfortunately errors are read by people and people are hard.
>>>>> :)
>>>>>
>>>>> --
>>>>> You received this message because you are subscribed to the Google
>>>>> Groups "Clojure" group.
>>>>> To post to this group, send email to clojure@googlegroups.com
>>>>> Note that posts from new members are moderated - please be patient
>>>>> with your first post.
>>>>> To unsubscribe from this group, send email to
>>>>> clojure+unsubscr...@googlegroups.com
>>>>> For more options, visit this group at
>>>>> http://groups.google.com/group/clojure?hl=en
>>>>> ---
>>>>> You received this message because you are subscribed to the Google
>>>>> Groups "Clojure" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>>> an email to clojure+unsubscr...@googlegroups.com.
>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>>
>>>> --
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure" group.
>>>> To post to this group, send email to clojure@googlegroups.com
>>>> Note that posts from new members are moderated - please be patient with
>>>> your first post.
>>>> To unsubscribe from this group, send email to
>>>> clojure+unsubscr...@googlegroups.com
>>>> For more options, visit this group at
>>>> http://groups.google.com/group/clojure?hl=en
>>>> ---
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>> an email to clojure+unsubscr...@googlegroups.com.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clojure@googlegroups.com
>>> Note that posts from new members are moderated - please be patient with
>>> your first post.
>>> To unsubscribe from this group, send email to
>>> clojure+unsubscr...@googlegroups.com
>>> For more options, visit this group at
>>> http://groups.google.com/group/clojure?hl=en
>>> ---
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to clojure+unsubscr...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to