Skip to content

Review usage of assert #95

Open
Open
@lread

Description

@lread

Raised me in rewrite-cljc-playground, see lread/rewrite-cljc-playground#59

Much thanks to @sogaiu for bringing this up on Slack.

Rewrite-clj (and therefore rewrite-cljc) makes use of assert, mostly to validate node creation, and therefore also for general parsing. The most common assertion is that a node has the expected number of children.

@sogaiu highlighted the following interesting points (which I am paraphrasing, hopefully correctly):

  1. the naive use of assert can lead to unintented results as described in "Use of Assertions" by John Regehr from which @sogaiu quoted:

    if we are writing library code, we must be even more careful to use assertions correctly than if we are writing a standalone application. The only time to assert something in library code is when the code truly cannot continue executing without dire consequences.

    @sogaiu also came across "Beware of Assertions" by Alexander Yakushev

  2. @borkdude effectively disables these asserts for some of his projects, for example here's how he does so for clj-kondo, mostly for performance.

If we take point 1 to heart, we can argue that rewrite-cljc really shouldn't be making use of assert. It should not be deciding that the situation of encountering invalid Clojure is dire for the calling library/application.

Note that I did replace all explicit Exception throws with ex-info exceptions for rewrite-cljc, for cross-platform support between clj and cljs - so I do have a precedent for replacing other types of exceptions. But I am not sure what makes sense moving forward. Some initial ideas:

  1. do nothing and document - this preserves backward compatibility
  2. replace with explicit throws - this would allow for a catchable Exception but would break behavior compatibility for folks who want to disable checks for performance (or other) reasons.
  3. replace with spec - but spec is not normally enabled in production, so backward compatibility behavior would be an opt-in, and depending on how far we go with spec, might more coarser grained that a caller would like?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    Medium Priority

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions