-
Notifications
You must be signed in to change notification settings - Fork 0
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
Name already taken #1
Comments
Just noticed from docs that, yes, you do know about clojure.spec. Thought I'd follow up with a name suggestion... fsharp.spec. In line with clojure.spec and has no ambiguity with FsSpec the testing library. |
Glad the project intrigues you! The library is currently usable and what it does is well covered with tests. Now the library needs use and feedback to feel out the rough edges in practical application. As to the name, do you have a link to the other FsSpec library? |
There's actually multiple GitHub repos with the name, but the one that matters is https://github.com/chaliy/fsspec which is a .NET/F# project. Granted, they don't have a NuGet package but I've seen the library referenced elsewhere. May not be the end of the world since they didn't create a package on nuget.org, but courtesy and avoiding confusion are reasons to at least consider it. |
Hmm. That project doesn't have a NuGet package and hasn't been touched in 12 years. I'll keep it in mind, but it doesn't feel pressing to make a change. I understand FSharp.spec, but I also hesitate because this library differs considerably from Clojure's spec system. There is no intent to take this library in the direction of set semantics or integrate it as part of the type system. Clojure.spec is built on predicates/expressions, which I considered and rejected as a sustainable approach for this library. Clojure.spec leans into Design-by-Contract-style assertions while this library embraces type-driven development. |
This does have me thinking about how this library enables Clojure.spec-style constraint "inheritance". One could build a core collection of common constraints or otherwise build up constraints in a readable way. let markdown = //...
let sanitizedMarkdown = markdown &&& //...
let recipeIngredientSpec = sanitizedMarkdown &&& notEmpty Do these semantic compositions of constraints need special representation? (maybe leaf type |
I'm a little confused by some of your clojure.spec descriptions. How is clojure.spec "part of the type system", especially when Clojure is a dynamic language? I'm also unsure what you mean by "Design-by-Contract-style assertions"? A constrained type is as much a "Design-by-Contract style assertion" as clojure.spec's are, and they are far more "part of the type system" than the wrappers added by clojure.spec. There are certainly differences between this and clojure.spec, where you're working within the type system of a strongly typed language and clojure.spec embraces the dynamic nature of the language it's working within. But in the end both are doing runtime type verification (even if, due to the nature of the strongly typed language, the runtime type verification here is confined only to data creation, rather than sprinkled everywhere). IMHO, neither is doing DbC, as you can't specify something like "when you pop from the stack the stack will have one less item" as you would in Eiffel's DbC. |
Thanks for sharing your thoughts. I'm enjoying how this makes me think differently. I'm not experienced in Eiffel, so I may not have the same understanding of DbC as you. But here are some of my reasonings Clojure.spec as DbC -> Clojure specs are primarily for use in decorating functions with pre- and post-conditions (including relationships between input and output). These conditions will throw exceptions if violated, as with DbC I've experienced in other places.
Clojure.spec is more a part of the type system -> F# certainly has a more rigorous type system and more types are leveraged to achieve a type-driven style. However, FsSpec is not essential to make any of that type-driven magic work. It can make it nicer, but all the type safety would be fine without it. Clojure, on the other hand, is dynamic as you've said. Spec is the language's approach to defining and enforcing types. I consider it similar to the optional type system TypeScript brings to Javascript or Sorbet to Ruby. This does have me realizing how easy it would be to make descriptive assertions using spec data. Something like let divide dividend divisor =
Spec.assert(NonNegativeInt, divisor)
divident/divisor The assertion can both check satisfaction and generate a descriptive exception from the spec. There are valid cases for this, even if I strongly prefer total functions over exceptions. It's easy enough I think individual users could implement it if they want it, and we can integrate it if there is enough demand. Something like module Spec =
let assert' spec value =
let valueExplanation = Spec.explain spec value
if Explanation.isOk valueExplanation.Explanation
then ()
else failwith (valueExplanation |> Formatters.prefix_allresults) Maybe also make a custom exception type. |
There's already an FsSpec, a BDD testing framework for F#, that will cause problems and confusion. I suggest you find a better name?
I found this project via F# weekly and the blog post at https://spencerfarley.com/draft/fsspec/. It intrigued me immediately. Are you aware of clojure.spec? If not, there's lots to learn from there, as it's a very similar system that's been battle hardened. I very much like the idea of being able to specify constraints as data and will be watching this project with interest, and may even contribute. Sorry, I know this is commentary and not part of the issue, but I don't see any other way to interact yet.
The text was updated successfully, but these errors were encountered: