Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

defn spec macro? #12

Closed
didibus opened this issue Nov 10, 2017 · 7 comments
Closed

defn spec macro? #12

didibus opened this issue Nov 10, 2017 · 7 comments

Comments

@didibus
Copy link

didibus commented Nov 10, 2017

On the Clojure mailing list, it was suggested that Orchestra was potentially working on adding a macro to replace def and defn, which would allow to define inline specs as the function/var is defined. Is this still on the roadmap?

@jeaye
Copy link
Owner

jeaye commented Nov 10, 2017

You're quite right, @didibus. Thanks for the reminder. Currently, we're using the below form for an alternative defn.

   ; Example usage
   (defn-spec str->kw keyword?
     [s ::spec.util/non-blank]
      (keyword s))

   ; Multiple arities are also supported
   (defn-spec inc' number?
     ([a number?]
      (inc' a 1))
     ([a number?, n number?]
      (+ a n)))

Others I've seen have gone for a sym :- spec syntax, but that implies that specs are optional. That doesn't fly with Orchestra's opinions on spec'ing, so any? should be used anywhere specs aren't otherwise provided.

We're currently using this, to great effect, but I haven't yet brought it into Orchestra. As for a timeline on this, I'll get it merged in tonight, with some tests and docs over the weekend.

I'm not sure about a solution for def though; that never ocurred to me. Do you have a suggestion for how that'd work?

@didibus
Copy link
Author

didibus commented Nov 12, 2017

I prefer that syntax to using :- as mentioned. I think if you don't want to spec everything, normal defn can do. And any? is always an option as you said.

Is there a place in the syntax for the fn spec? Like maybe after the arg list?

I guess I mentioned def without also really thinking about it. I guess something like this could maybe be useful:

(def-spec symbol-name value)
Where it would create a ::symbol-name keyword with spec.

My thinking is that on the def-spec evaluation, it could use set-validator! to set the spec as the validator for the var, and also validate the initial value. If the value is another reference type, it could also set-validator! the spec on it and validate initial value.

It would also now allow you to defn-spec a method and say it took [a ::symbol-name] as an argument.

Not sure about the def-spec idea though. Especially the smart part with reference types, could get confusing as to what you are speccing.

@jeaye
Copy link
Owner

jeaye commented Nov 12, 2017

Is there a place in the syntax for the fn spec? Like maybe after the arg list?

Clojure has built-in support for the meta map for functions, so defn-spec just rides on that. I have the macro merged and some tests pushed. You can see the full boat here: https://github.com/jeaye/orchestra/blob/master/test/cljc/orchestra/core_test.cljc#L47 as well as doc string support here: https://github.com/jeaye/orchestra/blob/master/test/cljc/orchestra/core_test.cljc#L72

Destructuring works, doc strings, meta maps. It should support everything defn does, since it uses the same specs to parse defn-spec as Clojure uses to parse defn.

@jeaye
Copy link
Owner

jeaye commented Nov 12, 2017

@didibus I have added docs and released 2017.11.12-1. Feedback would be much appreciated! The docs are here: https://github.com/jeaye/orchestra#defn-spec

@jeaye jeaye closed this as completed Nov 12, 2017
@sooheon
Copy link

sooheon commented Dec 24, 2018

@jeaye Now that this has been released for a while, do you have any experience getting Cursive to play nice with recognizing the syntax?

@jeaye
Copy link
Owner

jeaye commented Dec 24, 2018

@sooheon Nope, sorry! I work in Vim and the rest of my team is in Emacs. In Vim, for example, any form starting with defn.*, I think, gets indentation accordingly. If you do figure something out which Cursive requires, let me know and we can add it to the Orchestra readme. 🙂

@sooheon
Copy link

sooheon commented Dec 26, 2018

Thanks, I think this is just a matter of internal support in Cursive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants