Great conversation! I'm still catching up on Spec, but it seems like 
there's a correlation here to type systems. Type systems can introduce a 
certain kind of technical debt - type debt? It seems that leaving maps open 
here is also attempting to avoid that sort of type debt - parochial maps 
that don't play nice with others. And when we constrain maps in that closed 
way, aren't we creating some new subtype of a map, with fundamentally 
different semantics? If you are going to fully close a map, you might as 
well use a deftype and make a custom object and not call it a map, right?

On Wednesday, November 15, 2017 at 11:34:04 AM UTC-5, Eric Normand wrote:
>
> Wow, this has been a really great discussion. I have only played with spec 
> a little, not used it in production. Reading this and participating has 
> really helped me clarify a lot of things. Thanks!
>
> In particular, I've been thinking a lot about the three things you 
> mentioned, Didier: safety, compatibility, and correctness. I think it's 
> great that you pulled them apart. I've written a number of public-facing 
> APIs in my day, and what I always wound up doing was being really strict 
> with the clients because it actually helps correctness. It helps give 
> really fast feedback to third parties writing client code because they get 
> error messages about everything that's wrong with their request. Anything 
> that's silently accepted could mask a bigger problem and, especially with 
> third-party clients, you want to get those problems out in the open as soon 
> as possible.
>
> But the more I look at the behavior of s/keys, the more I'm starting to 
> appreciate it. It's not trying to be strict to educate clients. It's for 
> asking "does this have the minimum I need to handle this map?" And this is 
> very much how idiomatic Clojure is written. We ignore keys we don't care 
> about and pass them along. Or we select only the keys we care about and 
> operate on those. I wonder why we don't want to do this with our APIs. It's 
> so comfortable and practical internally.
>
> Now, the educational value of strictness (as developers write clients for 
> our API) is important. But it doesn't seem to be in the purview of spec. 
> I've been thinking about a few guidelines, because I haven't seen them 
> written down:
>
> 1. Use namespaced keywords with globally unique namespaces that you own.
> 2. Don't "invent" keys in a namespace you don't own.
> 3. Validate the keys you care about, to ensure that you have the minimum 
> you need to continue (using a s/keys spec) with appropriate types.
> 4. Handle extra keys you can't use in the appropriate way (ignore them and 
> pass them on OR select only the ones you want).
>
> With these, you actually do get a lot of the safety and correctness you're 
> talking about, but it's more of a systemic safety (unexpected input won't 
> break the system) and safety across changes (growth).
>
> There are still two problems that this won't solve. The first is the OP's 
> original problem, which was typos in keys allowing values with bad types to 
> get through a s/valid? check. That's serious but could easily be checked 
> with Stuart's code, using what Spec provides. So I think that's a real 
> solution provided by Spec. You could check in a test, for instance.
>
> The second problem is that education problem: you want clients to know 
> when they send typos, not just silently ignore them. I think this is 
> important. We've already got s/valid?, which asks "can I handle this?". 
> Maybe you could implement something called strict? that takes a spec and a 
> value and makes sure there aren't any extra keys. It doesn't seem to belong 
> in the spec. To me, it should go in a function which you could deploy when 
> you need it.
>
>
> Rock on!
> Eric
>
> On Tuesday, November 14, 2017 at 8:04:34 PM UTC-6, Didier wrote:
>>
>> | I think you're assuming you're validating API endpoints where client 
>> and server are tightly coupled. I can imagine a microservices system where 
>> some services put maps on a queue and others consume them. The consumers 
>> should allow keys they don't understand. They and also need to validate 
>> that the keys they need are there and of the right shape.
>>
>> That use case sounds more like the exception then the rule to me. I still 
>> think its valid, and for that I recognise there should be a way to have a 
>> spec which allows any key and requires specific ones.
>>
>> Now that I've listened to everyone, I see that there might be many things 
>> needed by different people, and its not clear if all should be provided by 
>> spec directly.
>>
>> Mostly I can see wanting:
>>   A. To spec a map in which you expect the keys to have a registered spec.
>>   B. To spec a map in which you don't expect the keys to have a 
>> registered spec.
>>   1. To spec a map in which the keys should be closed to only the req and 
>> opt keys that are defined. 
>>   2. To spec a map in which the keys should be open to what is defined, 
>> but where certain keys are required and others reserved as optional.
>>
>> Where we want to be able to mix and match A,B with 1,2.
>>
>> I see a safe default being A,1. Though I'd be okay with A,2. I think B is 
>> the bigger issue not to have as default, and is less intuitive. It's prone 
>> to typos and forgetting to add the spec or require the proper namespace, 
>> etc.
>>
>> My conclusion: I think s/keys is a funny part of spec, because compared 
>> to all other provided speccing tool, this one is really just syntax sugar 
>> for convenience. Yet it makes sense, because it is just so damn convenient. 
>> But for a lot of people like me, its convenient in a surprising way, which 
>> leans towards compatibility instead of correctness and security. And most 
>> baffling, trying to spec a map in a correct, secure and convenient way is 
>> not possible, at least not with the same convenience. So I'd say if there 
>> was just also convenient s/closed-keys and s/specified-keys and 
>> s/specified-closed-keys everyone would be happy, and it would also be more 
>> explicit what distinction exist between all 4. I'd probably always reach 
>> first for s/specified-closed-keys, and relax if I need too only, but all 
>> least everyone would have what they want and could chose for themselves.
>>
>>

-- 
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