Re: clojure.spec merge+or bug?

2019-10-14 Thread Alex Whitt
I got bitten by this today as well... makes it hard to add a predicate that 
destructures the map and compares its values. 

On Friday, August 17, 2018 at 4:35:12 PM UTC-4, Alex Miller wrote:
>
> With s/and, conformed values flow through the predicates. This allows you 
> to take advantage of structured values from early preds in later preds, so 
> you're not having to re-understand the structure. (There are cases where 
> having a non-flowing s/and would be useful and we've talked about adding 
> that since way back, still TBD). For single values, there's not much 
> difference, but it matters when you've got more structure, either from 
> regex (really s/& then) or s/or, etc.
>
> With s/merge the idea is to combine 2 or more map specs and "merge" their 
> specs, both during conform and gen. The mental picture I have is that the 
> same data flows into all the merged preds in parallel (whereas s/and snakes 
> them through in serial order). I don't have a good example at hand that 
> illustrates where is critical, but certainly in cases where you combining 
> s/keys with a collection view of map tuples with s/coll (sometimes called 
> "hybrid maps"), this is essential. 
>
>
>
> On Friday, August 17, 2018 at 2:36:23 PM UTC-5, Jenny Finkel wrote:
>>
>> Sorry, I meant to file a bug and even try to write a fix, but I was very 
>> pregnant at the time and then I gave birth so it sort of fell by the 
>> wayside. I'm interested in understanding why non-flowing behavior on 
>> conform is expected/desired behavior. I've found that when clojure design 
>> decisions go contrary to my intuitions, I usually learn a lot from 
>> understanding the design motivation. Would you mind explaining?
>> Cheers,
>>  Jenny
>> PS - I did try to google for an answer, and I found the thread where the 
>> docstring for merge got updated to reflect this, but I couldn't find an 
>> explanation.
>>
>> On Thu, Aug 16, 2018 at 7:00 PM, > 
>> wrote:
>>
>>> Thank you for explaining!
>>>
>>> Just in case, I opened a bug here 
>>> https://dev.clojure.org/jira/browse/CLJ-2388 
>>>
>>> On Thursday, August 16, 2018 at 6:47:30 PM UTC-7, Alex Miller wrote:

 The non-flowing behavior on conform is expected behavior.

 Failure to roundtrip conform then unform is a bug (so I'd so the bug 
 here is in unform).

 On a quick search, I don't believe this was filed, but I could have 
 missed it.

 On Thursday, August 16, 2018 at 8:28:54 PM UTC-5, shlomi...@gmail.com 
 wrote:
>
> Achhh, just spent the last few hours fighting this unexpected behavior 
> with s/merge, until I finally came to realize that this is what it was..
>
> I see this thread is quite old, did anyone open a bug for it as 
> mentioned above? 
>
> @Alex, you said this was the expected behavior, but then asked to open 
> a bug because it does not round-trip.. I am slightly confused, does the 
> problem lie in this "expected" behavior, or does it lie in s/unform? How 
> would such a bug be closed?
>
> Thanks,
> Shlomi
>
> On Thursday, June 1, 2017 at 6:24:25 AM UTC-7, Alex Miller wrote:
>>
>> You can file a bug on the s/merge unform - anything that doesn't 
>> roundtrip should be a bug.
>>
>> On the coll-of one, I thought that was just fixed in the latest 
>> spec.alpha release (see https://dev.clojure.org/jira/browse/CLJ-2076) 
>> - are you using latest there?
>>
> -- 
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clo...@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
>>> clo...@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 a topic in the 
>>> Google Groups "Clojure" group.
>>> To unsubscribe from this topic, visit 
>>> https://groups.google.com/d/topic/clojure/r8WO24rHsi0/unsubscribe.
>>> To unsubscribe from this group and all its topics, send an email to 
>>> clo...@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.
To view this discussion on 

Re: clojure.spec merge+or bug?

2018-08-17 Thread Alex Miller
With s/and, conformed values flow through the predicates. This allows you 
to take advantage of structured values from early preds in later preds, so 
you're not having to re-understand the structure. (There are cases where 
having a non-flowing s/and would be useful and we've talked about adding 
that since way back, still TBD). For single values, there's not much 
difference, but it matters when you've got more structure, either from 
regex (really s/& then) or s/or, etc.

With s/merge the idea is to combine 2 or more map specs and "merge" their 
specs, both during conform and gen. The mental picture I have is that the 
same data flows into all the merged preds in parallel (whereas s/and snakes 
them through in serial order). I don't have a good example at hand that 
illustrates where is critical, but certainly in cases where you combining 
s/keys with a collection view of map tuples with s/coll (sometimes called 
"hybrid maps"), this is essential. 



On Friday, August 17, 2018 at 2:36:23 PM UTC-5, Jenny Finkel wrote:
>
> Sorry, I meant to file a bug and even try to write a fix, but I was very 
> pregnant at the time and then I gave birth so it sort of fell by the 
> wayside. I'm interested in understanding why non-flowing behavior on 
> conform is expected/desired behavior. I've found that when clojure design 
> decisions go contrary to my intuitions, I usually learn a lot from 
> understanding the design motivation. Would you mind explaining?
> Cheers,
>  Jenny
> PS - I did try to google for an answer, and I found the thread where the 
> docstring for merge got updated to reflect this, but I couldn't find an 
> explanation.
>
> On Thu, Aug 16, 2018 at 7:00 PM,  wrote:
>
>> Thank you for explaining!
>>
>> Just in case, I opened a bug here 
>> https://dev.clojure.org/jira/browse/CLJ-2388 
>>
>> On Thursday, August 16, 2018 at 6:47:30 PM UTC-7, Alex Miller wrote:
>>>
>>> The non-flowing behavior on conform is expected behavior.
>>>
>>> Failure to roundtrip conform then unform is a bug (so I'd so the bug 
>>> here is in unform).
>>>
>>> On a quick search, I don't believe this was filed, but I could have 
>>> missed it.
>>>
>>> On Thursday, August 16, 2018 at 8:28:54 PM UTC-5, shlomi...@gmail.com 
>>> wrote:

 Achhh, just spent the last few hours fighting this unexpected behavior 
 with s/merge, until I finally came to realize that this is what it was..

 I see this thread is quite old, did anyone open a bug for it as 
 mentioned above? 

 @Alex, you said this was the expected behavior, but then asked to open 
 a bug because it does not round-trip.. I am slightly confused, does the 
 problem lie in this "expected" behavior, or does it lie in s/unform? How 
 would such a bug be closed?

 Thanks,
 Shlomi

 On Thursday, June 1, 2017 at 6:24:25 AM UTC-7, Alex Miller wrote:
>
> You can file a bug on the s/merge unform - anything that doesn't 
> roundtrip should be a bug.
>
> On the coll-of one, I thought that was just fixed in the latest 
> spec.alpha release (see https://dev.clojure.org/jira/browse/CLJ-2076) 
> - are you using latest there?
>
 -- 
>> 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 a topic in the 
>> Google Groups "Clojure" group.
>> To unsubscribe from this topic, visit 
>> https://groups.google.com/d/topic/clojure/r8WO24rHsi0/unsubscribe.
>> To unsubscribe from this group and all its topics, 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.


Re: clojure.spec merge+or bug?

2018-08-17 Thread Jenny Finkel
Sorry, I meant to file a bug and even try to write a fix, but I was very
pregnant at the time and then I gave birth so it sort of fell by the
wayside. I'm interested in understanding why non-flowing behavior on
conform is expected/desired behavior. I've found that when clojure design
decisions go contrary to my intuitions, I usually learn a lot from
understanding the design motivation. Would you mind explaining?
Cheers,
 Jenny
PS - I did try to google for an answer, and I found the thread where the
docstring for merge got updated to reflect this, but I couldn't find an
explanation.

On Thu, Aug 16, 2018 at 7:00 PM,  wrote:

> Thank you for explaining!
>
> Just in case, I opened a bug here https://dev.clojure.org/jira/
> browse/CLJ-2388
>
> On Thursday, August 16, 2018 at 6:47:30 PM UTC-7, Alex Miller wrote:
>>
>> The non-flowing behavior on conform is expected behavior.
>>
>> Failure to roundtrip conform then unform is a bug (so I'd so the bug here
>> is in unform).
>>
>> On a quick search, I don't believe this was filed, but I could have
>> missed it.
>>
>> On Thursday, August 16, 2018 at 8:28:54 PM UTC-5, shlomi...@gmail.com
>> wrote:
>>>
>>> Achhh, just spent the last few hours fighting this unexpected behavior
>>> with s/merge, until I finally came to realize that this is what it was..
>>>
>>> I see this thread is quite old, did anyone open a bug for it as
>>> mentioned above?
>>>
>>> @Alex, you said this was the expected behavior, but then asked to open a
>>> bug because it does not round-trip.. I am slightly confused, does the
>>> problem lie in this "expected" behavior, or does it lie in s/unform? How
>>> would such a bug be closed?
>>>
>>> Thanks,
>>> Shlomi
>>>
>>> On Thursday, June 1, 2017 at 6:24:25 AM UTC-7, Alex Miller wrote:

 You can file a bug on the s/merge unform - anything that doesn't
 roundtrip should be a bug.

 On the coll-of one, I thought that was just fixed in the latest
 spec.alpha release (see https://dev.clojure.org/jira/browse/CLJ-2076)
 - are you using latest there?

>>> --
> 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 a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/
> topic/clojure/r8WO24rHsi0/unsubscribe.
> To unsubscribe from this group and all its topics, 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.


Re: clojure.spec merge+or bug?

2018-08-16 Thread shlomivaknin
Thank you for explaining!

Just in case, I opened a bug here 
https://dev.clojure.org/jira/browse/CLJ-2388 

On Thursday, August 16, 2018 at 6:47:30 PM UTC-7, Alex Miller wrote:
>
> The non-flowing behavior on conform is expected behavior.
>
> Failure to roundtrip conform then unform is a bug (so I'd so the bug here 
> is in unform).
>
> On a quick search, I don't believe this was filed, but I could have missed 
> it.
>
> On Thursday, August 16, 2018 at 8:28:54 PM UTC-5, shlomi...@gmail.com 
>  wrote:
>>
>> Achhh, just spent the last few hours fighting this unexpected behavior 
>> with s/merge, until I finally came to realize that this is what it was..
>>
>> I see this thread is quite old, did anyone open a bug for it as mentioned 
>> above? 
>>
>> @Alex, you said this was the expected behavior, but then asked to open a 
>> bug because it does not round-trip.. I am slightly confused, does the 
>> problem lie in this "expected" behavior, or does it lie in s/unform? How 
>> would such a bug be closed?
>>
>> Thanks,
>> Shlomi
>>
>> On Thursday, June 1, 2017 at 6:24:25 AM UTC-7, Alex Miller wrote:
>>>
>>> You can file a bug on the s/merge unform - anything that doesn't 
>>> roundtrip should be a bug.
>>>
>>> On the coll-of one, I thought that was just fixed in the latest 
>>> spec.alpha release (see https://dev.clojure.org/jira/browse/CLJ-2076) - 
>>> are you using latest there?
>>>
>>

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


Re: clojure.spec merge+or bug?

2018-08-16 Thread Alex Miller
The non-flowing behavior on conform is expected behavior.

Failure to roundtrip conform then unform is a bug (so I'd so the bug here 
is in unform).

On a quick search, I don't believe this was filed, but I could have missed 
it.

On Thursday, August 16, 2018 at 8:28:54 PM UTC-5, shlomivak...@gmail.com 
wrote:
>
> Achhh, just spent the last few hours fighting this unexpected behavior 
> with s/merge, until I finally came to realize that this is what it was..
>
> I see this thread is quite old, did anyone open a bug for it as mentioned 
> above? 
>
> @Alex, you said this was the expected behavior, but then asked to open a 
> bug because it does not round-trip.. I am slightly confused, does the 
> problem lie in this "expected" behavior, or does it lie in s/unform? How 
> would such a bug be closed?
>
> Thanks,
> Shlomi
>
> On Thursday, June 1, 2017 at 6:24:25 AM UTC-7, Alex Miller wrote:
>>
>> You can file a bug on the s/merge unform - anything that doesn't 
>> roundtrip should be a bug.
>>
>> On the coll-of one, I thought that was just fixed in the latest 
>> spec.alpha release (see https://dev.clojure.org/jira/browse/CLJ-2076) - 
>> are you using latest there?
>>
>

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


Re: clojure.spec merge+or bug?

2018-08-16 Thread shlomivaknin
Achhh, just spent the last few hours fighting this unexpected behavior with 
s/merge, until I finally came to realize that this is what it was..

I see this thread is quite old, did anyone open a bug for it as mentioned 
above? 

@Alex, you said this was the expected behavior, but then asked to open a 
bug because it does not round-trip.. I am slightly confused, does the 
problem lie in this "expected" behavior, or does it lie in s/unform? How 
would such a bug be closed?

Thanks,
Shlomi

On Thursday, June 1, 2017 at 6:24:25 AM UTC-7, Alex Miller wrote:
>
> You can file a bug on the s/merge unform - anything that doesn't roundtrip 
> should be a bug.
>
> On the coll-of one, I thought that was just fixed in the latest spec.alpha 
> release (see https://dev.clojure.org/jira/browse/CLJ-2076) - are you 
> using latest there?
>

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


Re: clojure.spec gen-testing VS NaN

2018-03-07 Thread 'Dirk Wetzel' via Clojure
By definition NaN never equals any other number, including NaN itself, so 
isn't it a perfectly valid scenario to generate double NaNs?
(Note: I've not used spec yet, so correct me if I'm completely off track)


Am Montag, 7. November 2016 23:07:14 UTC+1 schrieb Alex Miller:
>
> I think it would be reasonable to log a jira enhancement request for the 
> spec any? generator to avoid generating double NaNs.
>
>
> On Monday, November 7, 2016 at 12:30:24 PM UTC-6, Jim foo.bar wrote:
>>
>> Hi Alex,
>>
>> Oh yeah I've seen `s/double-in` but as you point out that doesn't help me 
>> if I want to :ret spec a function with similar semantics as remove (a fn 
>> that transforms a seq given a predicate), which I find a very common 
>> indeed.  I'm only starting playing with clojure.spec (in fact i've only 
>> spec'ed 2 fns so far) and I've not yet had to spec specifically a 
>> double-precision number. I have had however the need to spec :any? as 
>> ::anything-but-NaN, in both my first 2 specs, so according to my experience 
>> this is by no means a rare issue. In fact, looking at clojure.core, most 
>> fns operate on seqs, and a good proportion of them processes/transforms a 
>> coll according to a predicate/fn. This has nothing to do with doubles or in 
>> fact numbers. We can only spec the contents of the collection as `any?` 
>> right? anything more specific, and the gen-surface area is reduced. So yeah 
>> it's great that we have `s/double-in`, but ideally I'd also like a reliable 
>> way to say that the output coll from a fn is equal to the input coll, while 
>> having specified the contents of that coll with `any?`, and without having 
>> to jump through hoops in the :ret spec. My workaround is actually working 
>> nicely for me, and i can certainly live without NaNs in the tests, but it 
>> still feels a bit hacky.
>>
>> Thanks,
>>
>> Dimitris
>>
>> On 07/11/16 18:14, Alex Miller wrote:
>>
>> Please also take a look at s/double-in, which allows you to exclude NaN 
>> (and Infinity/-Infinity) as valid values. 
>>
>> (I realize this does not address the any? question, but that seems like a 
>> rarer issue to me than cases where I'm explicitly spec'ing a double but 
>> don't want to allow NaN.)
>>
>> On Monday, November 7, 2016 at 11:37:08 AM UTC-6, Jim foo.bar wrote: 
>>>
>>> Hi all, 
>>>
>>> clojure.spec helped me realise that NaNs totally break [1] equality (per 
>>> `clojure.core/=`). Even though in real production code this might not be 
>>> an issue due to how infrequently one deals with NaNs, but during 
>>> gen-testing I've found them extremely annoying, and I've essentially 
>>> worked around this by spec-ing things I'd normally specify via `any?`, 
>>> via `(s/and any? (complement double-NaN?))` instead. I have to do this 
>>> for any spec, where in the :ret spec i need to be able to confirm that 
>>> the input coll is equal to the output coll (e.g. `clojure.core/remove` 
>>> returns the same coll it was passed in when nothing has been removed), 
>>> which is a possibility in a lot of functions. Have other people 
>>> encountered this as well, and if yes, how are you guys dealing with it? 
>>> Thanks in advance... 
>>>
>>> Kind regards, 
>>>
>>> Dimitris 
>>>
>>> [1]: (= [:a Double/NaN] [:a Double/NaN]) => false 
>>>
>>>
>>>
>>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@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+u...@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+u...@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.


Re: clojure.spec gen-testing VS NaN

2018-03-06 Thread Wes Morgan
Yes it did: https://dev.clojure.org/jira/browse/CLJ-2054

On Tuesday, March 6, 2018 at 12:15:26 PM UTC-7, Wes Morgan wrote:
>
> Did this ticket get created?
>
> On Monday, November 7, 2016 at 3:26:15 PM UTC-7, Jim foo.bar wrote:
>>
>> Alright cool, I'll do that tomorrow :) 
>>
>> Thanks,
>>
>> Dimitris
>>
>> On 07/11/16 22:07, Alex Miller wrote:
>>
>> I think it would be reasonable to log a jira enhancement request for the 
>> spec any? generator to avoid generating double NaNs. 
>>
>>
>> On Monday, November 7, 2016 at 12:30:24 PM UTC-6, Jim foo.bar wrote: 
>>>
>>> Hi Alex,
>>>
>>> Oh yeah I've seen `s/double-in` but as you point out that doesn't help 
>>> me if I want to :ret spec a function with similar semantics as remove (a fn 
>>> that transforms a seq given a predicate), which I find a very common 
>>> indeed.  I'm only starting playing with clojure.spec (in fact i've only 
>>> spec'ed 2 fns so far) and I've not yet had to spec specifically a 
>>> double-precision number. I have had however the need to spec :any? as 
>>> ::anything-but-NaN, in both my first 2 specs, so according to my experience 
>>> this is by no means a rare issue. In fact, looking at clojure.core, most 
>>> fns operate on seqs, and a good proportion of them processes/transforms a 
>>> coll according to a predicate/fn. This has nothing to do with doubles or in 
>>> fact numbers. We can only spec the contents of the collection as `any?` 
>>> right? anything more specific, and the gen-surface area is reduced. So yeah 
>>> it's great that we have `s/double-in`, but ideally I'd also like a reliable 
>>> way to say that the output coll from a fn is equal to the input coll, while 
>>> having specified the contents of that coll with `any?`, and without having 
>>> to jump through hoops in the :ret spec. My workaround is actually working 
>>> nicely for me, and i can certainly live without NaNs in the tests, but it 
>>> still feels a bit hacky.
>>>
>>> Thanks,
>>>
>>> Dimitris
>>>
>>> On 07/11/16 18:14, Alex Miller wrote:
>>>
>>> Please also take a look at s/double-in, which allows you to exclude NaN 
>>> (and Infinity/-Infinity) as valid values. 
>>>
>>> (I realize this does not address the any? question, but that seems like 
>>> a rarer issue to me than cases where I'm explicitly spec'ing a double but 
>>> don't want to allow NaN.)
>>>
>>> On Monday, November 7, 2016 at 11:37:08 AM UTC-6, Jim foo.bar wrote: 

 Hi all, 

 clojure.spec helped me realise that NaNs totally break [1] equality 
 (per 
 `clojure.core/=`). Even though in real production code this might not 
 be 
 an issue due to how infrequently one deals with NaNs, but during 
 gen-testing I've found them extremely annoying, and I've essentially 
 worked around this by spec-ing things I'd normally specify via `any?`, 
 via `(s/and any? (complement double-NaN?))` instead. I have to do this 
 for any spec, where in the :ret spec i need to be able to confirm that 
 the input coll is equal to the output coll (e.g. `clojure.core/remove` 
 returns the same coll it was passed in when nothing has been removed), 
 which is a possibility in a lot of functions. Have other people 
 encountered this as well, and if yes, how are you guys dealing with it? 
 Thanks in advance... 

 Kind regards, 

 Dimitris 

 [1]: (= [:a Double/NaN] [:a Double/NaN]) => false 



 -- 
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clo...@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+u...@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+u...@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 clo...@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+u...@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+u...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>>
>>

-- 
You received this message because you are subscribed to the Google

Re: clojure.spec gen-testing VS NaN

2018-03-06 Thread Wes Morgan
Did this ticket get created?

On Monday, November 7, 2016 at 3:26:15 PM UTC-7, Jim foo.bar wrote:
>
> Alright cool, I'll do that tomorrow :) 
>
> Thanks,
>
> Dimitris
>
> On 07/11/16 22:07, Alex Miller wrote:
>
> I think it would be reasonable to log a jira enhancement request for the 
> spec any? generator to avoid generating double NaNs. 
>
>
> On Monday, November 7, 2016 at 12:30:24 PM UTC-6, Jim foo.bar wrote: 
>>
>> Hi Alex,
>>
>> Oh yeah I've seen `s/double-in` but as you point out that doesn't help me 
>> if I want to :ret spec a function with similar semantics as remove (a fn 
>> that transforms a seq given a predicate), which I find a very common 
>> indeed.  I'm only starting playing with clojure.spec (in fact i've only 
>> spec'ed 2 fns so far) and I've not yet had to spec specifically a 
>> double-precision number. I have had however the need to spec :any? as 
>> ::anything-but-NaN, in both my first 2 specs, so according to my experience 
>> this is by no means a rare issue. In fact, looking at clojure.core, most 
>> fns operate on seqs, and a good proportion of them processes/transforms a 
>> coll according to a predicate/fn. This has nothing to do with doubles or in 
>> fact numbers. We can only spec the contents of the collection as `any?` 
>> right? anything more specific, and the gen-surface area is reduced. So yeah 
>> it's great that we have `s/double-in`, but ideally I'd also like a reliable 
>> way to say that the output coll from a fn is equal to the input coll, while 
>> having specified the contents of that coll with `any?`, and without having 
>> to jump through hoops in the :ret spec. My workaround is actually working 
>> nicely for me, and i can certainly live without NaNs in the tests, but it 
>> still feels a bit hacky.
>>
>> Thanks,
>>
>> Dimitris
>>
>> On 07/11/16 18:14, Alex Miller wrote:
>>
>> Please also take a look at s/double-in, which allows you to exclude NaN 
>> (and Infinity/-Infinity) as valid values. 
>>
>> (I realize this does not address the any? question, but that seems like a 
>> rarer issue to me than cases where I'm explicitly spec'ing a double but 
>> don't want to allow NaN.)
>>
>> On Monday, November 7, 2016 at 11:37:08 AM UTC-6, Jim foo.bar wrote: 
>>>
>>> Hi all, 
>>>
>>> clojure.spec helped me realise that NaNs totally break [1] equality (per 
>>> `clojure.core/=`). Even though in real production code this might not be 
>>> an issue due to how infrequently one deals with NaNs, but during 
>>> gen-testing I've found them extremely annoying, and I've essentially 
>>> worked around this by spec-ing things I'd normally specify via `any?`, 
>>> via `(s/and any? (complement double-NaN?))` instead. I have to do this 
>>> for any spec, where in the :ret spec i need to be able to confirm that 
>>> the input coll is equal to the output coll (e.g. `clojure.core/remove` 
>>> returns the same coll it was passed in when nothing has been removed), 
>>> which is a possibility in a lot of functions. Have other people 
>>> encountered this as well, and if yes, how are you guys dealing with it? 
>>> Thanks in advance... 
>>>
>>> Kind regards, 
>>>
>>> Dimitris 
>>>
>>> [1]: (= [:a Double/NaN] [:a Double/NaN]) => false 
>>>
>>>
>>>
>>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@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+u...@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+u...@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 clo...@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+u...@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+u...@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

Re: [clojure.spec] Best practices for programmatically generating specs?

2017-12-14 Thread Aaron Brooks
An eval requirement will still be an impediment to me but it's good to hear 
that things are still being worked on. I'm happy to do any early testing of 
proposed approaches and give feedback.

Thanks for letting me know -- keep us posted!

-Aaron

On Wednesday, December 13, 2017 at 10:45:56 PM UTC-5, Alex Miller wrote:
>
> Another possible option is using spec specs (CLJ-2112) to unform from a 
> spec data form to a spec (but that would still need to be evaluated) - 
> still very much a wip.
>
> However, we are working on a spec update that will target some of this, so 
> stay tuned for that.
>
>
>
> On Wednesday, December 13, 2017 at 5:14:34 PM UTC-6, Aaron Brooks wrote:
>>
>> I've found in several projects that I want to have families of specs that 
>> have some shared structure but some differing structure.
>>
>> Consider a case where I have some, possibly nested, structure which in 
>> some cases will have some type of  place-holder values which will later be 
>> replaced with actual values. I don't want a spec to have an 's/or at each 
>> position that could have a place-holder since I expect the structure to be 
>> populated with only place-holder values or only resolved values and want to 
>> exclude a mix.
>>
>> Neither do I want to maintain two versions of the spec by hand. Some of 
>> the structure is complex and would be a pain to keep the two in sync.
>>
>> This appears to leave two choices.
>>
>> I'd like to describe the spec and then walk the spec, generating the 
>> other spec instance. Due to the macro-y nature of spec, I think this means 
>> eval which makes this not cljc/cljs friendly for self-hosted ClojureScript.
>>
>> The alternative seems to be to build a set of macros that will generate 
>> both forms of the specs. This is awkward since it requires the full spec to 
>> be defined within the macro form and winds up being much more complex than 
>> a walk-and-transform of one spec into another.
>>
>> What is the best practice for generating specs like this? Am I missing 
>> something?
>>
>> I'm afraid the current macro-y, non-data-y implementation of 
>> clojure.spec.alpha really renders certain usage patterns (say specs that 
>> are derived from meta-specs) very awkward or inaccessible. I know spec 
>> needs to capture symbols and forms but wish that was a ease interface on 
>> top of a data oriented implementation that was first-class.
>>
>> Let me know if I'm missing something in how I'm thinking about this or 
>> what my available options are.
>>
>> Thanks!
>>
>> -Aaron
>>
>

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


Re: [clojure.spec] Best practices for programmatically generating specs?

2017-12-13 Thread Alex Miller
Another possible option is using spec specs (CLJ-2112) to unform from a 
spec data form to a spec (but that would still need to be evaluated) - 
still very much a wip.

However, we are working on a spec update that will target some of this, so 
stay tuned for that.



On Wednesday, December 13, 2017 at 5:14:34 PM UTC-6, Aaron Brooks wrote:
>
> I've found in several projects that I want to have families of specs that 
> have some shared structure but some differing structure.
>
> Consider a case where I have some, possibly nested, structure which in 
> some cases will have some type of  place-holder values which will later be 
> replaced with actual values. I don't want a spec to have an 's/or at each 
> position that could have a place-holder since I expect the structure to be 
> populated with only place-holder values or only resolved values and want to 
> exclude a mix.
>
> Neither do I want to maintain two versions of the spec by hand. Some of 
> the structure is complex and would be a pain to keep the two in sync.
>
> This appears to leave two choices.
>
> I'd like to describe the spec and then walk the spec, generating the other 
> spec instance. Due to the macro-y nature of spec, I think this means eval 
> which makes this not cljc/cljs friendly for self-hosted ClojureScript.
>
> The alternative seems to be to build a set of macros that will generate 
> both forms of the specs. This is awkward since it requires the full spec to 
> be defined within the macro form and winds up being much more complex than 
> a walk-and-transform of one spec into another.
>
> What is the best practice for generating specs like this? Am I missing 
> something?
>
> I'm afraid the current macro-y, non-data-y implementation of 
> clojure.spec.alpha really renders certain usage patterns (say specs that 
> are derived from meta-specs) very awkward or inaccessible. I know spec 
> needs to capture symbols and forms but wish that was a ease interface on 
> top of a data oriented implementation that was first-class.
>
> Let me know if I'm missing something in how I'm thinking about this or 
> what my available options are.
>
> Thanks!
>
> -Aaron
>

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


RE: clojure.spec - Using :pre conditions (or not)?

2017-06-08 Thread David Goldfarb
Agreed; I was just following up on your previous comments.

But, it is useful to have something that can be used in a precondition and also 
shows an explanation.

I’m using, basically, (or (s/valid? spec x) (s/explain spec x)). It would be 
good to have this built-in too.

From: clojure@googlegroups.com [mailto:clojure@googlegroups.com] On Behalf Of 
Alex Miller
Sent: Wednesday, June 7, 2017 5:46 PM
To: Clojure <clojure@googlegroups.com>
Subject: Re: clojure.spec - Using :pre conditions (or not)?

Preconditions are already assertions, so it makes more sense to use s/assert in 
your code body than in a precondition.

On Wednesday, June 7, 2017 at 8:12:22 AM UTC-5, David Goldfarb wrote:
One big downside of using s/assert in a precondition:  It does not work with 
(s/nilable ...) specs, since s/assert returns valid values.

I fell into this trap for a moment of head-scratching just now.

On Wednesday, September 14, 2016 at 4:59:09 PM UTC+3, Alex Miller wrote:
Another option that has been added since the guide was written is s/assert 
which seems closer to what you're suggesting.

(defn name [user]
  {:pre [(s/assert :common/user user)]}
  (-> user :user/name))

;; need to enable assertion checking - this can also be enabled globally with 
system property clojure.spec.check-asserts
(s/check-asserts true)

(name {:user/name "Elon"})
"Elon"

(name {:x "Elon"})
ExceptionInfo Spec assertion failed
val: {:x "Elon"} fails predicate: (contains? % :user/name)
:clojure.spec/failure  :assertion-failed
  clojure.core/ex-info (core.clj:4725)

Rather than use it in a precondition, you can also use s/assert directly in the 
code.

On Wednesday, September 14, 2016 at 7:37:24 AM UTC-5, 
joakim.t...@nova.com<mailto:joakim.t...@nova.com> wrote:

(ns spec-test.core
  (:require [clojure.spec :as s]))

(s/def :user/name string?)
(s/def :common/user (s/keys :req [:user/name]))

; first version of name (using :pre)
(defn name [user]
  {:pre [(s/valid? :common/user user)]}
  (-> user :user/name))

; This statement works ok and returns "Elon":
(name {:user/name "Elon"})

; but this statement...
(name {:x "Elon"})

;...will throw:
CompilerException java.lang.AssertionError:
Assert failed: (s/valid? :common/user user)

; ...but then I don't get as much information
; about the error as if I would have called:
(s/explain :common/user {:x "Elon"})

;...which also contains the predicate:
val: {:x "Elon"} fails spec: :common/user
predicate: (contains? % :user/name)

; (second version of name - more verbose)
; or do I need to wite it like this:
(defn name [user]
  (let [parsed (s/conform :common/user user)]
(if (= parsed ::s/invalid)
  (throw (ex-info "Invalid input" (s/explain-data :common/user user)))
  (-> user :user/name

; so that:
(name {:x "Elon"})

; ...will return:
CompilerException clojure.lang.ExceptionInfo:
  Invalid input #:clojure.spec{:problems}
({:path [], :pred (contains? % :user/name),
  :val {:x "Elon"}, :via [:common/user], :in []})

; It should be nice if I could be able to write it like this
; (or similar, to get a better error message):
(defn name [user]
  {:pre [(s/explain :common/user user)]}
  (-> user :user/name))
--
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<mailto: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<mailto: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 a topic in the Google 
Groups "Clojure" group.
To unsubscribe from this topic, visit 
https://groups.google.com/d/topic/clojure/H9tk04sSTWE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to 
clojure+unsubscr...@googlegroups.com<mailto: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.


Re: clojure.spec - Using :pre conditions (or not)?

2017-06-07 Thread Alex Miller
Preconditions are already assertions, so it makes more sense to use 
s/assert in your code body than in a precondition.

On Wednesday, June 7, 2017 at 8:12:22 AM UTC-5, David Goldfarb wrote:
>
> One big downside of using s/assert in a precondition:  It does not work 
> with (s/nilable ...) specs, since s/assert returns valid values.
>
> I fell into this trap for a moment of head-scratching just now.
>
> On Wednesday, September 14, 2016 at 4:59:09 PM UTC+3, Alex Miller wrote:
>>
>> Another option that has been added since the guide was written is 
>> s/assert which seems closer to what you're suggesting.
>>
>> (defn name [user]
>>   {:pre [(s/assert :common/user user)]}
>>   (-> user :user/name))
>>
>> ;; need to enable assertion checking - this can also be enabled globally 
>> with system property clojure.spec.check-asserts
>> (s/check-asserts true)
>>
>> (name {:user/name "Elon"})
>> "Elon"
>>
>> (name {:x "Elon"})
>> ExceptionInfo Spec assertion failed
>> val: {:x "Elon"} fails predicate: (contains? % :user/name)
>> :clojure.spec/failure  :assertion-failed
>>   clojure.core/ex-info (core.clj:4725)
>>
>> Rather than use it in a precondition, you can also use s/assert directly 
>> in the code.
>>
>> On Wednesday, September 14, 2016 at 7:37:24 AM UTC-5, 
>> joakim.t...@nova.com wrote:
>>>
>>> (ns spec-test.core
>>>   (:require [clojure.spec :as s]))
>>>
>>> (s/def :user/name string?)
>>> (s/def :common/user (s/keys :req [:user/name]))
>>>
>>> ; first version of name (using :pre)
>>> (defn name [user]
>>>   {:pre [(s/valid? :common/user user)]}
>>>   (-> user :user/name))
>>>
>>> ; This statement works ok and returns "Elon":
>>> (name {:user/name "Elon"})
>>>
>>> ; but this statement...
>>> (name {:x "Elon"})
>>>
>>> ;...will throw:
>>> CompilerException java.lang.AssertionError:
>>> Assert failed: (s/valid? :common/user user)
>>>
>>> ; ...but then I don't get as much information
>>> ; about the error as if I would have called:
>>> (s/explain :common/user {:x "Elon"})
>>>
>>> ;...which also contains the predicate:
>>> val: {:x "Elon"} fails spec: :common/user
>>> predicate: (contains? % :user/name)
>>>
>>> ; (second version of name - more verbose)
>>> ; or do I need to wite it like this:
>>> (defn name [user]
>>>   (let [parsed (s/conform :common/user user)]
>>> (if (= parsed ::s/invalid)
>>>   (throw (ex-info "Invalid input" (s/explain-data :common/user user)))
>>>   (-> user :user/name
>>>
>>> ; so that:
>>> (name {:x "Elon"})
>>>
>>> ; ...will return:
>>> CompilerException clojure.lang.ExceptionInfo:
>>>   Invalid input #:clojure.spec{:problems}
>>> ({:path [], :pred (contains? % :user/name),
>>>   :val {:x "Elon"}, :via [:common/user], :in []})
>>>
>>> ; It should be nice if I could be able to write it like this
>>> ; (or similar, to get a better error message):
>>> (defn name [user]
>>>   {:pre [(s/explain :common/user user)]}
>>>   (-> user :user/name))
>>>
>>>

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


Re: clojure.spec - Using :pre conditions (or not)?

2017-06-07 Thread David Goldfarb
One big downside of using s/assert in a precondition:  It does not work 
with (s/nilable ...) specs, since s/assert returns valid values.

I fell into this trap for a moment of head-scratching just now.

On Wednesday, September 14, 2016 at 4:59:09 PM UTC+3, Alex Miller wrote:
>
> Another option that has been added since the guide was written is s/assert 
> which seems closer to what you're suggesting.
>
> (defn name [user]
>   {:pre [(s/assert :common/user user)]}
>   (-> user :user/name))
>
> ;; need to enable assertion checking - this can also be enabled globally 
> with system property clojure.spec.check-asserts
> (s/check-asserts true)
>
> (name {:user/name "Elon"})
> "Elon"
>
> (name {:x "Elon"})
> ExceptionInfo Spec assertion failed
> val: {:x "Elon"} fails predicate: (contains? % :user/name)
> :clojure.spec/failure  :assertion-failed
>   clojure.core/ex-info (core.clj:4725)
>
> Rather than use it in a precondition, you can also use s/assert directly 
> in the code.
>
> On Wednesday, September 14, 2016 at 7:37:24 AM UTC-5, joakim.t...@nova.com 
>  wrote:
>>
>> (ns spec-test.core
>>   (:require [clojure.spec :as s]))
>>
>> (s/def :user/name string?)
>> (s/def :common/user (s/keys :req [:user/name]))
>>
>> ; first version of name (using :pre)
>> (defn name [user]
>>   {:pre [(s/valid? :common/user user)]}
>>   (-> user :user/name))
>>
>> ; This statement works ok and returns "Elon":
>> (name {:user/name "Elon"})
>>
>> ; but this statement...
>> (name {:x "Elon"})
>>
>> ;...will throw:
>> CompilerException java.lang.AssertionError:
>> Assert failed: (s/valid? :common/user user)
>>
>> ; ...but then I don't get as much information
>> ; about the error as if I would have called:
>> (s/explain :common/user {:x "Elon"})
>>
>> ;...which also contains the predicate:
>> val: {:x "Elon"} fails spec: :common/user
>> predicate: (contains? % :user/name)
>>
>> ; (second version of name - more verbose)
>> ; or do I need to wite it like this:
>> (defn name [user]
>>   (let [parsed (s/conform :common/user user)]
>> (if (= parsed ::s/invalid)
>>   (throw (ex-info "Invalid input" (s/explain-data :common/user user)))
>>   (-> user :user/name
>>
>> ; so that:
>> (name {:x "Elon"})
>>
>> ; ...will return:
>> CompilerException clojure.lang.ExceptionInfo:
>>   Invalid input #:clojure.spec{:problems}
>> ({:path [], :pred (contains? % :user/name),
>>   :val {:x "Elon"}, :via [:common/user], :in []})
>>
>> ; It should be nice if I could be able to write it like this
>> ; (or similar, to get a better error message):
>> (defn name [user]
>>   {:pre [(s/explain :common/user user)]}
>>   (-> user :user/name))
>>
>>

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


Re: clojure.spec merge+or bug?

2017-06-01 Thread Alex Miller
You can file a bug on the s/merge unform - anything that doesn't roundtrip 
should be a bug.

On the coll-of one, I thought that was just fixed in the latest spec.alpha 
release (see https://dev.clojure.org/jira/browse/CLJ-2076) - are you using 
latest there?

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


Re: clojure.spec merge+or bug?

2017-05-31 Thread Jenny Finkel
It also seems to come up with coll-of + or:

user> (s/def ::a (s/or :even even? :odd odd?))
user> (s/def ::c (s/coll-of ::a))
user> (s/conform ::c [1 2 3 4])
[[:odd 1] [:even 2] [:odd 3] [:even 4]]
user> (s/unform ::c (s/conform ::c [1 2 3 4]))
[[:odd 1] [:even 2] [:odd 3] [:even 4]]

It looks like coll-of calls every-impl which just has identity as it's 
unform fn.
-Jenny

On Wednesday, May 31, 2017 at 9:37:43 PM UTC-7, Jenny Finkel wrote:
>
> I think I found a bug in spec when combining merge and or. Basically, when 
> you conform a map where one of the keys has an or, and the spec comes from 
> a clojure.spec/merge, one of the underlying keys will conform it, while the 
> others don't, and then when the results get merged together you can end up 
> with the unconformed version in the result:
>
> user> (require '[clojure.spec :as s])
> user> (s/def ::a (s/or :even even? :odd odd?))
> user> (s/def ::b (s/or :even even? :odd odd?))
> user> (s/def ::m1 (s/keys :req-un [::a]))
> user> (s/def ::m2 (s/keys :req-un [::b]))
> user> (s/def ::mm (s/merge ::m1 ::m2))
> user> (s/valid? ::mm {:a 1 :b 2})
> true
> user> (s/conform ::mm {:a 1 :b 2})
> {:a 1, :b [:even 2]}
> user> (s/unform ::mm {:a [:odd 1] :b [:even 2]})
> {:a 1, :b [:even 2]}
> user> (s/unform ::mm (s/conform ::mm {:a 1 :b 2}))
> UnsupportedOperationException nth not supported on this type: Long 
>  clojure.lang.RT.nthFrom (RT.java:962)
>
> I guess that valid? checks if it satisfies all the merged specs, and 
> conform conforms on each and merges, and then unform can end up with a 
> result that it can't unform (and similarly, if you give unform a properly 
> conformed thing it can't unform properly due to how it merges results as 
> well). I think the fix would be an update to clojure.spec/merge to make it 
> smarter about which keys to keep from each map on conforming and unforming, 
> though looking at the current code I don't think it's an easy fix.
>
> -Jenny
>

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


Re: clojure.spec merge+or bug?

2017-05-31 Thread Jenny Finkel
thanks for the fast reply! do you think it will always be this way? it does
seem to violate the expected conform/unform relationship.

On Wed, May 31, 2017 at 9:51 PM, Alex Miller  wrote:

> This is actually the expected result. s/merge doesn't flow like s/and -
> only the conformed version of the last map spec in the merge is used. There
> are thus some unexpected results in combination with the -un options as
> they are the only link towards conforming.
>
> One thing you could try instead is to use s/and which does flow and might
> give you some of the behavior you're looking for (but won't gen as well).
>
> --
> 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 a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/
> topic/clojure/r8WO24rHsi0/unsubscribe.
> To unsubscribe from this group and all its topics, 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.


Re: clojure.spec merge+or bug?

2017-05-31 Thread Jenny Finkel
PS - I just realize I wasn't using the latest version of spec, as is 
evident from my require, but I just tried again with the latest and it 
doesn't change the result. And I should have mentioned that I'm happy to 
take a stab at a fix, assuming I'm correct that this is a bug.

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


Re: [clojure.spec/form] Need for evaluated subspecs

2017-05-22 Thread marian . hornak
Thanks Alex,

I am surprised by info that *"s/and (and all of the spec forms) are macros 
to facilitate capturing the spec form for use in s/form and error 
reporting." *but everything makes sense considering it.

Marián

On Thursday, May 18, 2017 at 6:35:46 PM UTC+2, Alex Miller wrote:
>
>
>
> On Wednesday, May 17, 2017 at 3:02:17 PM UTC-5, marian...@vacuumlabs.com 
>  wrote:
>>
>> Hi,
>>
>> I am writing a function that transforms Specs to another formats (similar 
>> to the JSON Schema). Assuming from this post 
>> ,
>>  
>> I am not the only one. There is no surprise that I am using 
>> clojure.spec/form. Unfortunately I am not fully satisfied with its 
>> output. To illustrate the problem let's suppose that my transformer will be 
>> used by a third person who like to write its own spec-generating helpers:
>>
>> (require '[clojure.spec.alpha :as spec])
>>
>> (spec/def ::forgivable-keyword (spec/conformer (fn [x] (cond (keyword? x) 
>> x
>>  (string? x) 
>> (keyword x)
>>  true 
>> ::spec/invalid
>>
>> (defn kw-enum [& enum-values] (spec/and ::forgivable-keyword (apply 
>> hash-set enum-values)))
>>
>>
> s/and (and all of the spec forms) are macros to facilitate capturing the 
> spec form for use in s/form and error reporting.
>
> In this case, (apply hash-set enum-values) is not either a predicate or a 
> set and thus is not a valid spec to use in s/and. 
>
> I presume what you're looking for is the ability to dynamically create 
> specs - for this, please consider using either eval or a macro.
>
>  
>
>> Cool! Let's look how can my transformer cope with it!
>>
>> (spec/form (kw-enum :a :b :c))
>> ; (clojure.spec.alpha/and 
>> :my-ns/forgivable-keyword (clojure.core/apply clojure.core/hash-set 
>> enum-values))
>>
>> Ouch! Have I just seen a local symbol in the form? I am sorry third 
>> person, I won't be able to transform the output of your spec-generating 
>> functions. Unless they are macros:
>>
>> (defmacro kw-enum [& enum-values] `(spec/and ::forgivable-keyword ~(apply 
>> hash-set enum-values)))
>>
>> (spec/form (kw-enum :a :b :c))
>> ; (clojure.spec.alpha/and :my-ns/forgivable-keyword #{:c :b :a})
>>
>> This approach looks better. How does it work in combination with other 
>> specs?
>>
>> (spec/form (spec/nilable (kw-enum :a :b :c)))
>> ; (clojure.spec.alpha/nilable (my-ns/kw-enum :a :b :c))
>>
>> There we are. A third-person's function is in the form. We could use eval to 
>> resolve it, but do we want to? 
>>
>
> Sure. It resolved to a spec last time, why not this time? OR, why do you 
> need to resolve it at all? (this to some degree depends on the use case)
>  
>
>> It has been already evaluated once. What if there are some side effects?
>>
>
> Then I'd say you already have more important problems.
>  
>
>> Practically, one has no option to write spec-generating function and 
>> maintain usability of the spec/form at the same time. Therefore one of 
>> four situations must have happened. Either I got something wrong, Specs are 
>> not meant to be introspected, Specs are not meant to be generated or 
>> spec/form is badly designed. Which one is it?
>>
>
> Seems to me like you can generate and introspect this fine. I think that 
> if you are introspecting spec forms, you will encounter resolved symbols 
> referring to functions. How you approach the use of those depends on your 
> context.
>
> Another option still coming (work in progress) is to use specs on spec 
> forms (CLJ-2112) to create conformed spec data, then s/unform back to a 
> spec form. 
>  
>
>>
>> (In the case of the fourth one I have some suggestions, but lets keep 
>> them for later conversation)
>>
>> Thanks for your time
>>
>> Marian
>>
>

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


Re: [clojure.spec/form] Need for evaluated subspecs

2017-05-20 Thread Leon Grapenthin
Hi Alex, thanks for replying. Indeed I don't have practical use for s/form 
right now; I'm just trying to guess what could be a good use in the future 
:) 

On Thursday, May 18, 2017 at 10:01:25 PM UTC+2, Alex Miller wrote:
>
>
>
> On Thursday, May 18, 2017 at 12:37:26 PM UTC-5, Leon Grapenthin wrote:
>>
>> I also have this problem. 
>>
>> 1. If I create a dynamic spec constructor per defmacro and invoke it, 
>> it's s/form gives the primitive specs form - because spec doesn't provide 
>> me with a way to facilitate specs that capture their form.
>>
>
> The idea of providing custom form serialization support is one I have 
> spent quite a bit of time looking at (in particular wrt s/&, s/keys*, and 
> the range specs, but in practice the same problem is being worked around in 
> the coll specs, etc). I've done spikes on three possible directions for 
> this and I can't say any of them is an unambiguous win so it's going to 
> require some Rich time at some point to make further decisions. In some 
> ways it's an analogous problem to how custom gens are implemented.
>  
>
>> 2. If I apply that invocation to another primitive spec, s/form of that 
>> just contains the macro invocation form.
>>
>> If this is intentional, I'd also like to know the underlying design rule 
>> (not the reasons why that is so in the current implementation): Why should 
>> this result in two different forms for one and the same spec to deal with, 
>> instead of one.
>>
>
> The principle is to capture the spec form at the time of construction for 
> the purposes of a) reporting and b) serialization via s/form. That seems 
> satisfied in both cases. 
>  
>
>> The reason to create "dynamic" spec constructors is usually to avoid 
>> boilerplate when writing specs. Unless I'm missing what I shouldn't do, I'd 
>> prefer to have direct support for that spares me having to deal with two 
>> forms.
>>
>
> In what way are you "dealing with" two forms? Why is that a problem?
>  
>
>>
>> Kind regards,
>>  Leon.
>>
>> On Thursday, May 18, 2017 at 6:35:46 PM UTC+2, Alex Miller wrote:
>>>
>>>
>>>
>>> On Wednesday, May 17, 2017 at 3:02:17 PM UTC-5, marian...@vacuumlabs.com 
>>> wrote:

 Hi,

 I am writing a function that transforms Specs to another formats 
 (similar to the JSON Schema). Assuming from this post 
 ,
  
 I am not the only one. There is no surprise that I am using 
 clojure.spec/form. Unfortunately I am not fully satisfied with its 
 output. To illustrate the problem let's suppose that my transformer will 
 be 
 used by a third person who like to write its own spec-generating helpers:

 (require '[clojure.spec.alpha :as spec])

 (spec/def ::forgivable-keyword (spec/conformer (fn [x] (cond (keyword? 
 x) x
  (string? 
 x) (keyword x)
  true 
 ::spec/invalid

 (defn kw-enum [& enum-values] (spec/and ::forgivable-keyword (apply 
 hash-set enum-values)))


>>> s/and (and all of the spec forms) are macros to facilitate capturing the 
>>> spec form for use in s/form and error reporting.
>>>
>>> In this case, (apply hash-set enum-values) is not either a predicate or 
>>> a set and thus is not a valid spec to use in s/and. 
>>>
>>> I presume what you're looking for is the ability to dynamically create 
>>> specs - for this, please consider using either eval or a macro.
>>>
>>>  
>>>
 Cool! Let's look how can my transformer cope with it!

 (spec/form (kw-enum :a :b :c))
 ; (clojure.spec.alpha/and 
 :my-ns/forgivable-keyword (clojure.core/apply clojure.core/hash-set 
 enum-values))

 Ouch! Have I just seen a local symbol in the form? I am sorry third 
 person, I won't be able to transform the output of your spec-generating 
 functions. Unless they are macros:

 (defmacro 
 kw-enum [& enum-values] `(spec/and ::forgivable-keyword ~(apply 
 hash-set enum-values)))

 (spec/form (kw-enum :a :b :c))
 ; (clojure.spec.alpha/and :my-ns/forgivable-keyword #{:c :b :a})

 This approach looks better. How does it work in combination with other 
 specs?

 (spec/form (spec/nilable (kw-enum :a :b :c)))
 ; (clojure.spec.alpha/nilable (my-ns/kw-enum :a :b :c))

 There we are. A third-person's function is in the form. We could use 
 eval to resolve it, but do we want to? 

>>>
>>> Sure. It resolved to a spec last time, why not this time? OR, why do you 
>>> need to resolve it at all? (this to some degree depends on the use case)
>>>  
>>>
 It has been already evaluated once. What if there are some side effects?

>>>
>>> Then I'd say you already have more important problems.
>>>  
>>>
 Practically, one has no option to write 

Re: [clojure.spec/form] Need for evaluated subspecs

2017-05-18 Thread Alex Miller


On Thursday, May 18, 2017 at 12:37:26 PM UTC-5, Leon Grapenthin wrote:
>
> I also have this problem. 
>
> 1. If I create a dynamic spec constructor per defmacro and invoke it, it's 
> s/form gives the primitive specs form - because spec doesn't provide me 
> with a way to facilitate specs that capture their form.
>

The idea of providing custom form serialization support is one I have spent 
quite a bit of time looking at (in particular wrt s/&, s/keys*, and the 
range specs, but in practice the same problem is being worked around in the 
coll specs, etc). I've done spikes on three possible directions for this 
and I can't say any of them is an unambiguous win so it's going to require 
some Rich time at some point to make further decisions. In some ways it's 
an analogous problem to how custom gens are implemented.
 

> 2. If I apply that invocation to another primitive spec, s/form of that 
> just contains the macro invocation form.
>
> If this is intentional, I'd also like to know the underlying design rule 
> (not the reasons why that is so in the current implementation): Why should 
> this result in two different forms for one and the same spec to deal with, 
> instead of one.
>

The principle is to capture the spec form at the time of construction for 
the purposes of a) reporting and b) serialization via s/form. That seems 
satisfied in both cases. 
 

> The reason to create "dynamic" spec constructors is usually to avoid 
> boilerplate when writing specs. Unless I'm missing what I shouldn't do, I'd 
> prefer to have direct support for that spares me having to deal with two 
> forms.
>

In what way are you "dealing with" two forms? Why is that a problem?
 

>
> Kind regards,
>  Leon.
>
> On Thursday, May 18, 2017 at 6:35:46 PM UTC+2, Alex Miller wrote:
>>
>>
>>
>> On Wednesday, May 17, 2017 at 3:02:17 PM UTC-5, marian...@vacuumlabs.com 
>> wrote:
>>>
>>> Hi,
>>>
>>> I am writing a function that transforms Specs to another formats 
>>> (similar to the JSON Schema). Assuming from this post 
>>> ,
>>>  
>>> I am not the only one. There is no surprise that I am using 
>>> clojure.spec/form. Unfortunately I am not fully satisfied with its 
>>> output. To illustrate the problem let's suppose that my transformer will be 
>>> used by a third person who like to write its own spec-generating helpers:
>>>
>>> (require '[clojure.spec.alpha :as spec])
>>>
>>> (spec/def ::forgivable-keyword (spec/conformer (fn [x] (cond (keyword? 
>>> x) x
>>>  (string? x) 
>>> (keyword x)
>>>  true 
>>> ::spec/invalid
>>>
>>> (defn kw-enum [& enum-values] (spec/and ::forgivable-keyword (apply 
>>> hash-set enum-values)))
>>>
>>>
>> s/and (and all of the spec forms) are macros to facilitate capturing the 
>> spec form for use in s/form and error reporting.
>>
>> In this case, (apply hash-set enum-values) is not either a predicate or a 
>> set and thus is not a valid spec to use in s/and. 
>>
>> I presume what you're looking for is the ability to dynamically create 
>> specs - for this, please consider using either eval or a macro.
>>
>>  
>>
>>> Cool! Let's look how can my transformer cope with it!
>>>
>>> (spec/form (kw-enum :a :b :c))
>>> ; (clojure.spec.alpha/and 
>>> :my-ns/forgivable-keyword (clojure.core/apply clojure.core/hash-set 
>>> enum-values))
>>>
>>> Ouch! Have I just seen a local symbol in the form? I am sorry third 
>>> person, I won't be able to transform the output of your spec-generating 
>>> functions. Unless they are macros:
>>>
>>> (defmacro 
>>> kw-enum [& enum-values] `(spec/and ::forgivable-keyword ~(apply 
>>> hash-set enum-values)))
>>>
>>> (spec/form (kw-enum :a :b :c))
>>> ; (clojure.spec.alpha/and :my-ns/forgivable-keyword #{:c :b :a})
>>>
>>> This approach looks better. How does it work in combination with other 
>>> specs?
>>>
>>> (spec/form (spec/nilable (kw-enum :a :b :c)))
>>> ; (clojure.spec.alpha/nilable (my-ns/kw-enum :a :b :c))
>>>
>>> There we are. A third-person's function is in the form. We could use 
>>> eval to resolve it, but do we want to? 
>>>
>>
>> Sure. It resolved to a spec last time, why not this time? OR, why do you 
>> need to resolve it at all? (this to some degree depends on the use case)
>>  
>>
>>> It has been already evaluated once. What if there are some side effects?
>>>
>>
>> Then I'd say you already have more important problems.
>>  
>>
>>> Practically, one has no option to write spec-generating function and 
>>> maintain usability of the spec/form at the same time. Therefore one of 
>>> four situations must have happened. Either I got something wrong, Specs are 
>>> not meant to be introspected, Specs are not meant to be generated or 
>>> spec/form is badly designed. Which one is it?
>>>
>>
>> Seems to me like you can generate and introspect this fine. I 

Re: [clojure.spec/form] Need for evaluated subspecs

2017-05-18 Thread Leon Grapenthin
I also have this problem. 

1. If I create a dynamic spec constructor per defmacro and invoke it, it's 
s/form gives the primitive specs form - because spec doesn't provide me 
with a way to facilitate specs that capture their form.

2. If I apply that invocation to another primitive spec, s/form of that 
just contains the macro invocation form.

If this is intentional, I'd also like to know the underlying design rule 
(not the reasons why that is so in the current implementation): Why should 
this result in two different forms for one and the same spec to deal with, 
instead of one.

The reason to create "dynamic" spec constructors is usually to avoid 
boilerplate when writing specs. Unless I'm missing what I shouldn't do, I'd 
prefer to have direct support for that spares me having to deal with two 
forms.

Kind regards,
 Leon.

On Thursday, May 18, 2017 at 6:35:46 PM UTC+2, Alex Miller wrote:
>
>
>
> On Wednesday, May 17, 2017 at 3:02:17 PM UTC-5, marian...@vacuumlabs.com 
>  wrote:
>>
>> Hi,
>>
>> I am writing a function that transforms Specs to another formats (similar 
>> to the JSON Schema). Assuming from this post 
>> ,
>>  
>> I am not the only one. There is no surprise that I am using 
>> clojure.spec/form. Unfortunately I am not fully satisfied with its 
>> output. To illustrate the problem let's suppose that my transformer will be 
>> used by a third person who like to write its own spec-generating helpers:
>>
>> (require '[clojure.spec.alpha :as spec])
>>
>> (spec/def ::forgivable-keyword (spec/conformer (fn [x] (cond (keyword? x) 
>> x
>>  (string? x) 
>> (keyword x)
>>  true 
>> ::spec/invalid
>>
>> (defn kw-enum [& enum-values] (spec/and ::forgivable-keyword (apply 
>> hash-set enum-values)))
>>
>>
> s/and (and all of the spec forms) are macros to facilitate capturing the 
> spec form for use in s/form and error reporting.
>
> In this case, (apply hash-set enum-values) is not either a predicate or a 
> set and thus is not a valid spec to use in s/and. 
>
> I presume what you're looking for is the ability to dynamically create 
> specs - for this, please consider using either eval or a macro.
>
>  
>
>> Cool! Let's look how can my transformer cope with it!
>>
>> (spec/form (kw-enum :a :b :c))
>> ; (clojure.spec.alpha/and 
>> :my-ns/forgivable-keyword (clojure.core/apply clojure.core/hash-set 
>> enum-values))
>>
>> Ouch! Have I just seen a local symbol in the form? I am sorry third 
>> person, I won't be able to transform the output of your spec-generating 
>> functions. Unless they are macros:
>>
>> (defmacro kw-enum [& enum-values] `(spec/and ::forgivable-keyword ~(apply 
>> hash-set enum-values)))
>>
>> (spec/form (kw-enum :a :b :c))
>> ; (clojure.spec.alpha/and :my-ns/forgivable-keyword #{:c :b :a})
>>
>> This approach looks better. How does it work in combination with other 
>> specs?
>>
>> (spec/form (spec/nilable (kw-enum :a :b :c)))
>> ; (clojure.spec.alpha/nilable (my-ns/kw-enum :a :b :c))
>>
>> There we are. A third-person's function is in the form. We could use eval to 
>> resolve it, but do we want to? 
>>
>
> Sure. It resolved to a spec last time, why not this time? OR, why do you 
> need to resolve it at all? (this to some degree depends on the use case)
>  
>
>> It has been already evaluated once. What if there are some side effects?
>>
>
> Then I'd say you already have more important problems.
>  
>
>> Practically, one has no option to write spec-generating function and 
>> maintain usability of the spec/form at the same time. Therefore one of 
>> four situations must have happened. Either I got something wrong, Specs are 
>> not meant to be introspected, Specs are not meant to be generated or 
>> spec/form is badly designed. Which one is it?
>>
>
> Seems to me like you can generate and introspect this fine. I think that 
> if you are introspecting spec forms, you will encounter resolved symbols 
> referring to functions. How you approach the use of those depends on your 
> context.
>
> Another option still coming (work in progress) is to use specs on spec 
> forms (CLJ-2112) to create conformed spec data, then s/unform back to a 
> spec form. 
>  
>
>>
>> (In the case of the fourth one I have some suggestions, but lets keep 
>> them for later conversation)
>>
>> Thanks for your time
>>
>> Marian
>>
>

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

Re: [clojure.spec/form] Need for evaluated subspecs

2017-05-18 Thread Alex Miller


On Wednesday, May 17, 2017 at 3:02:17 PM UTC-5, 
marian.hor...@vacuumlabs.com wrote:
>
> Hi,
>
> I am writing a function that transforms Specs to another formats (similar 
> to the JSON Schema). Assuming from this post 
> ,
>  
> I am not the only one. There is no surprise that I am using 
> clojure.spec/form. Unfortunately I am not fully satisfied with its 
> output. To illustrate the problem let's suppose that my transformer will be 
> used by a third person who like to write its own spec-generating helpers:
>
> (require '[clojure.spec.alpha :as spec])
>
> (spec/def ::forgivable-keyword (spec/conformer (fn [x] (cond (keyword? x) x
>  (string? x) 
> (keyword x)
>  true 
> ::spec/invalid
>
> (defn kw-enum [& enum-values] (spec/and ::forgivable-keyword (apply 
> hash-set enum-values)))
>
>
s/and (and all of the spec forms) are macros to facilitate capturing the 
spec form for use in s/form and error reporting.

In this case, (apply hash-set enum-values) is not either a predicate or a 
set and thus is not a valid spec to use in s/and. 

I presume what you're looking for is the ability to dynamically create 
specs - for this, please consider using either eval or a macro.

 

> Cool! Let's look how can my transformer cope with it!
>
> (spec/form (kw-enum :a :b :c))
> ; (clojure.spec.alpha/and 
> :my-ns/forgivable-keyword (clojure.core/apply clojure.core/hash-set 
> enum-values))
>
> Ouch! Have I just seen a local symbol in the form? I am sorry third 
> person, I won't be able to transform the output of your spec-generating 
> functions. Unless they are macros:
>
> (defmacro kw-enum [& enum-values] `(spec/and ::forgivable-keyword ~(apply 
> hash-set enum-values)))
>
> (spec/form (kw-enum :a :b :c))
> ; (clojure.spec.alpha/and :my-ns/forgivable-keyword #{:c :b :a})
>
> This approach looks better. How does it work in combination with other 
> specs?
>
> (spec/form (spec/nilable (kw-enum :a :b :c)))
> ; (clojure.spec.alpha/nilable (my-ns/kw-enum :a :b :c))
>
> There we are. A third-person's function is in the form. We could use eval to 
> resolve it, but do we want to? 
>

Sure. It resolved to a spec last time, why not this time? OR, why do you 
need to resolve it at all? (this to some degree depends on the use case)
 

> It has been already evaluated once. What if there are some side effects?
>

Then I'd say you already have more important problems.
 

> Practically, one has no option to write spec-generating function and 
> maintain usability of the spec/form at the same time. Therefore one of 
> four situations must have happened. Either I got something wrong, Specs are 
> not meant to be introspected, Specs are not meant to be generated or 
> spec/form is badly designed. Which one is it?
>

Seems to me like you can generate and introspect this fine. I think that if 
you are introspecting spec forms, you will encounter resolved symbols 
referring to functions. How you approach the use of those depends on your 
context.

Another option still coming (work in progress) is to use specs on spec 
forms (CLJ-2112) to create conformed spec data, then s/unform back to a 
spec form. 
 

>
> (In the case of the fourth one I have some suggestions, but lets keep them 
> for later conversation)
>
> Thanks for your time
>
> Marian
>

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


Re: Clojure.spec: need function equivalents of library macros?

2017-05-09 Thread Alex Miller

On Tuesday, May 9, 2017 at 6:21:29 AM UTC-5, Dave Tenny wrote:
>
> My issues aren't about qualified or unqualified keys (and the APIs 
> generally need to accept unqualified keys - I do use qualified keys in 
> various contexts, just not this post where the topic is macros vs. 
> non-macro forms).
>

spec pushes you towards qualified keys for good reasons (see Rich's 
original rationale), so I don't expect that we'll be adding more support 
for unqualified keys. The support that is there is intended as a bridge 
towards qualified keys.
 

> s/merge is a good point about composition.  However often all I really 
> want to do is take some list of, say, keywords, acceptable in a map or 
> collection that is a parameter, and 'disj' one keyword from it for another 
> spec because that particular keyword isn't valid or supported for an 
> interface in question.
>

I have found that when I'm seeing this a lot, either the code is not 
modeling the domain well by not factoring common attributes OR my domain 
structures are actually very dynamic and have many optional attributes that 
can occur in any combination. In the former case, I can usually step back 
and refactor the code so that attributes that are always grouped together 
have their own unit and functions. 

In the latter case, the key is often to spec less. Instead of trying to 
identify every attribute on every function input and output, just create a 
single map spec with all of the optional attributes. You can then constrain 
it further if needed by doing (s/merge ::common (s/keys :req [::foo 
::bar])) if needed.

Or another approach is to just use (s/keys) to validate all the attributes 
that happen to be in a map flowing through a function. This is exactly the 
use case that spec makes possible that few other validation approaches can 
handle well (the case of checking arbitrary attributes flowing through a 
system) and its enabled by the use of qualified names with global semantics.

At the end of the day, I feel I'm often forced to cut and paste too many 
> similar but different lists into various specs (fdef in particular).  The 
> ability to construct specs without macros might be useful.  
>

We don't have them available yet, but we will have specs for spec forms 
(see CLJ-2112). With specs for spec forms, you can programmatically 
transform or construct maps in this way. With spec forms, you can start 
from a spec, s/conform to data, manipulate that data in any way you like, 
then s/unform back to a spec. You can also start in the middle and 
construct the conformed data version of a spec and s/unform to the list 
form.

 

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


Re: Clojure.spec: need function equivalents of library macros?

2017-05-09 Thread Dave Tenny
My issues aren't about qualified or unqualified keys (and the APIs
generally need to accept unqualified keys - I do use qualified keys in
various contexts, just not this post where the topic is macros vs.
non-macro forms).

s/merge is a good point about composition.  However often all I really want
to do is take some list of, say, keywords, acceptable in a map or
collection that is a parameter, and 'disj' one keyword from it for another
spec because that particular keyword isn't valid or supported for an
interface in question.

At the end of the day, I feel I'm often forced to cut and paste too many
similar but different lists into various specs (fdef in particular).  The
ability to construct specs without macros might be useful.

On Tue, May 9, 2017 at 6:05 AM, Alex Miller  wrote:

> Is there any reason why you're using unqualified keys? If you're using
> qualified keys, then a simple (s/keys) spec will validate all registered
> keys in the map so you can cover all of your optional attribute cases that
> way.
>
> Another possibility worth mentioning is using s/merge to combine
> well-known (smaller) map specs into larger combinations.
>
>
> On Monday, May 8, 2017 at 10:38:34 AM UTC-5, Dave Tenny wrote:
>>
>> Let's say I have a namespace that provides access to the database,
>> say our table has these fields (as clojure specs)
>>
>> (s/def ::job-id nat-int?) ; 1 2 3 ...
>> (s/def ::job-name string?) ; frobozz-executor
>> (s/def ::job-status keyword?) ; :queued, :in-progress, :completed
>>
>>
>> And that I have the logic in place to convert to/from the types (e.g.
>> keywords).
>>
>> If I have a simple function to return records in from the jobs table it
>> might look like:
>>
>> (s/def ::job-record (s/keys :req-un [::job-id ::job-name ::job-status]))
>>
>> (s/fdef get-jobs
>>   :args (s/cat :db database-handle?)
>>   :ret (s/coll-of ::job-record))
>>
>> (defn get-jobs
>>   [db]
>>   ... returns vector of maps, one for each record, jdbc-style ...)
>>
>> (get-jobs) => [{:job-id 1 :job-name "frobozz-executor" :job-status
>> :queued} ...]
>>
>> Now here's where things get iffy in practice.  Suppose I have other
>> database interfaces that take similar but different maps or collections of
>> keywords.
>>
>> For example, a function like:
>>
>> (s/fdef get-selective-jobs
>>   :args (s/cat :db database-handle? :fields (s/keys :opt-un [::job-id
>> ::job-name ::job-status])))
>>
>> (defn get-selective-jobs
>>   [db fields]
>>   ... return only fields from the database that are specified in the
>> fields parameter ...)
>>
>>
>> Once you start getting some similar-but-different specs, it'd be nice
>> apply a bit of code building.
>>
>> e.g.
>>
>> (def job-field-keys [::job-id ::job-name ::job-status])
>>
>> (s/def ::job-record (s/keys* :req-un job-field-keys))
>> (s/fdef get-selective-args
>>   :args (s/cat* :db database-handle? :fields  (s/keys :opt-un
>> job-field-keys))
>>
>> Hopefully this is conducive to some thought/discussion of the subject,
>> and/or someone can just let me know how I should be doing this if there's
>> an easy way in the present spec implementation.
>>
>> Sidewise plea: inline specs for s/keys like you can do for s/cat.  s/keys
>> deliberate omision of inline specs does occasionally get in the way in
>> large namespaces.
>>
>>
>>
>> --
> 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 a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/
> topic/clojure/OBbq-jInyqI/unsubscribe.
> To unsubscribe from this group and all its topics, 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.


Re: Clojure.spec: need function equivalents of library macros?

2017-05-09 Thread Alex Miller
Is there any reason why you're using unqualified keys? If you're using 
qualified keys, then a simple (s/keys) spec will validate all registered 
keys in the map so you can cover all of your optional attribute cases that 
way.

Another possibility worth mentioning is using s/merge to combine well-known 
(smaller) map specs into larger combinations.


On Monday, May 8, 2017 at 10:38:34 AM UTC-5, Dave Tenny wrote:
>
> Let's say I have a namespace that provides access to the database,
> say our table has these fields (as clojure specs)
>
> (s/def ::job-id nat-int?) ; 1 2 3 ...
> (s/def ::job-name string?) ; frobozz-executor
> (s/def ::job-status keyword?) ; :queued, :in-progress, :completed
>
>
> And that I have the logic in place to convert to/from the types (e.g. 
> keywords).
>
> If I have a simple function to return records in from the jobs table it 
> might look like:
>
> (s/def ::job-record (s/keys :req-un [::job-id ::job-name ::job-status]))
>
> (s/fdef get-jobs
>   :args (s/cat :db database-handle?)
>   :ret (s/coll-of ::job-record))
>
> (defn get-jobs
>   [db]
>   ... returns vector of maps, one for each record, jdbc-style ...)
>
> (get-jobs) => [{:job-id 1 :job-name "frobozz-executor" :job-status 
> :queued} ...]
>
> Now here's where things get iffy in practice.  Suppose I have other 
> database interfaces that take similar but different maps or collections of 
> keywords.
>
> For example, a function like:
>
> (s/fdef get-selective-jobs
>   :args (s/cat :db database-handle? :fields (s/keys :opt-un [::job-id 
> ::job-name ::job-status])))
>
> (defn get-selective-jobs
>   [db fields]
>   ... return only fields from the database that are specified in the 
> fields parameter ...)
>
>
> Once you start getting some similar-but-different specs, it'd be nice 
> apply a bit of code building.
>
> e.g.
>
> (def job-field-keys [::job-id ::job-name ::job-status])
>
> (s/def ::job-record (s/keys* :req-un job-field-keys))
> (s/fdef get-selective-args
>   :args (s/cat* :db database-handle? :fields  (s/keys :opt-un 
> job-field-keys))
>
> Hopefully this is conducive to some thought/discussion of the subject, 
> and/or someone can just let me know how I should be doing this if there's 
> an easy way in the present spec implementation.
>
> Sidewise plea: inline specs for s/keys like you can do for s/cat.  s/keys 
> deliberate omision of inline specs does occasionally get in the way in 
> large namespaces.
>   
>
>
>

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


Re: Clojure.spec: need function equivalents of library macros?

2017-05-08 Thread Dave Tenny
Oops, some corrections to my original post.

On Monday, May 8, 2017 at 11:38:34 AM UTC-4, Dave Tenny wrote:
>
> Let's say I have a namespace that provides access to the database,
> say our table has these fields (as clojure specs)
>
> (s/def ::job-id nat-int?) ; 1 2 3 ...
> (s/def ::job-name string?) ; frobozz-executor
> (s/def ::job-status keyword?) ; :queued, :in-progress, :completed
>
>
> And that I have the logic in place to convert to/from the types (e.g. 
> keywords).
>
> If I have a simple function to return records in from the jobs table it 
> might look like:
>
> (s/def ::job-record (s/keys :req-un [::job-id ::job-name ::job-status]))
>
> (s/fdef get-jobs
>   :args (s/cat :db database-handle?)
>   :ret (s/coll-of ::job-record))
>
> (defn get-jobs
>   [db]
>   ... returns vector of maps, one for each record, jdbc-style ...)
>
> (get-jobs) => [{:job-id 1 :job-name "frobozz-executor" :job-status 
> :queued} ...]
>
> Now here's where things get iffy in practice.  Suppose I have other 
> database interfaces that take similar but different maps or collections of 
> keywords.
>
> For example, a function like this which lets you specify which fields you 
> want retrieved:
>
> (s/fdef get-selective-jobs
>   :args (s/cat :db database-handle? :fields (s/coll-of #{:job-id :job-name 
> :job-status}))
>
  :ret (s/coll-of (s/keys :opt-un [ ::job-id ::job-name ::job-status 
])))

^^ correction of :fields above, additiobn of :ret


> (defn get-selective-jobs
>   [db fields]
>   ... return only fields from the database that are specified in the 
> fields parameter ...)
>
>
> Once you start getting some similar-but-different specs, it'd be nice 
> apply a bit of code building.
>
> e.g.
>
> (def job-field-keys [::job-id ::job-name ::job-status])
>
> (s/def ::job-record (s/keys* :req-un job-field-keys))
> (s/fdef get-selective-args
>   :args (s/cat* :db database-handle? :fields  (s/coll-of (set 
> job-field-keys))
>
:ret (s/coll-of (s/keys* :opt-un job-field-keys)))

^^ correction to :args above, addition of :ret


> Hopefully this is conducive to some thought/discussion of the subject, 
> and/or someone can just let me know how I should be doing this if there's 
> an easy way in the present spec implementation.
>

The point being that it's be nice to have some easier ways of specifying 
similar but different sets of data in
s/keys, s/cat, s/coll-of, and possibly other macros.

 

>
> Sidewise plea: inline specs for s/keys like you can do for s/cat.  s/keys 
> deliberate omision of inline specs does occasionally get in the way in 
> large namespaces.
>   
>
>
>

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


Re: clojure.spec explain and multi-arity functions with first optional argument

2017-04-23 Thread Leon Grapenthin
Please try whether my CLJ-2013 
 patch fixes the issue for 
you. From my observation it should.

On Saturday, April 22, 2017 at 7:31:48 PM UTC+2, Yegor Timoshenko wrote:
>
> (require '[clojure.spec :as s])
> (require '[clojure.spec.test :refer [instrument]])
>
> (defn request ([url]) ([params url]))
>
> (s/fdef request
>   :args (s/cat :params (s/? map?) :url string?))
>
> (instrument `request)
> (request [] "")
>
> ExceptionInfo Call to #'user/request did not conform to spec:
> In: [0] val: [] fails at: [:args :url] predicate: string?
> :clojure.spec/args  ([] "")
> :clojure.spec/failure  :instrument
> :clojure.spec.test/caller  {:file "form-init1226863901212006294.clj", 
> :line 1, :var-scope user/eval2193}
>   clojure.core/ex-info (core.clj:4725)
>
> I expected that it would fail at `map?` predicate rather than at `string?` 
> predicate.
> s/or produces better explanation, but at the same time is relatively more 
> verbose:
>
> (require '[clojure.spec :as s])
> (require '[clojure.spec.test :refer [instrument]])
>
> (defn request ([url]) ([params url]))
>
> (s/fdef request
>   :args (s/or :simple (s/cat :url string?)
>:advanced (s/cat :params map? :url string?)))
>
> (instrument `request)
> (request [] "")
>
> ExceptionInfo Call to #'user/request did not conform to spec:
> In: [0] val: [] fails at: [:args :simple :url] predicate: string?
> In: [0] val: [] fails at: [:args :advanced :params] predicate: map?
> :clojure.spec/args  ([] "")
> :clojure.spec/failure  :instrument
> :clojure.spec.test/caller  {:file "form-init1226863901212006294.clj", 
> :line 1, :var-scope user/eval2208}
>   clojure.core/ex-info (core.clj:4725)
>
> Is it subject to improvement? https://dev.clojure.org/jira/browse/CLJ-1982 
> might be the same issue.
>

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


Re: clojure.spec s/keys map key with alternative definitions in same namespace

2017-02-07 Thread Dave Tenny
>From my perspective, there are two specs.  I'm not trying to mash them
together, however I would like to use the appropriate spec with the same
keyword in maps, in different contexts.

It wouldn't be an issue if the contexts were in separate namespaces.  It's
only an issue because the two specs are in the same namespace, and I want
to use them in different places with the same map key.

(Or so it seems to me, still wrapping my head around spec).

On Tue, Feb 7, 2017 at 11:10 AM, Alex Miller  wrote:

> Spec names are intended to have enduring global semantics. So the notion
> of the same spec name having different semantics at different times seems
> to be at odds with that.
>
> In general, it's often helpful to think about all the possible values that
> an attribute will have - that's the true spec. In this case, it seems like
> what you have for ::coercible-job-type is the true spec - it can be either
> a string or other named value.
>
> And then think about the places where you need to add additional
> constraints to your ::job-record spec to narrow it. Like maybe here:
>
> (s/fdef ... :ret (s/and ::job-record #(-> % ::job-type string?)))
>
> You're on the brink of suggesting subtypes and covariant / contravariants,
> etc and that's a path spec is not going down.
>
>
> On Tuesday, February 7, 2017 at 9:40:24 AM UTC-6, Dave Tenny wrote:
>>
>> Let's say I have these definitions for a "job" record I'm managing,
>> perhaps in a database.
>>
>> (s/def ::job-status #{:in-progress :completed})
>> (s/def ::user-id (s/and integer? #(>= % 0)))
>> (s/def ::job-id integer?)
>>
>> (s/def ::coercible-job-type (s/and named? #(not (empty? (name %)
>> (s/def ::job-type (s/and string? #(not (empty? %
>>
>> So we have a job status which can be any of a limited set of keywords,
>> integer user and job ID's.
>>
>> Then there's job type and my issue.  Depending on the context I want
>> either to insist that job type will be purely a non-empty string, or that
>> it may also be a 'named?' object,
>> i.e. something for which the clojure.core/name function will work.
>>
>> If I'm just returning a pure job record, my definition would look like
>> this:
>>
>> (s/def ::job-record
>>   (s/keys :req-un [::job-id ::user-id ::job-type ::job-status]))
>>
>> So a map with all those keys and type definitions. And that's great.  I
>> define functions that return these
>> maps and so there's an (s/fdef ... :ret ::job-record).
>>
>> Now let's say I have an update! function that can take a map of optional
>> fields and update the record in the database with the fields that were
>> specified.
>>
>> (s/def ::field-options (s/keys :opt-un [::job-id ::user-id ::job-type
>> ::job-status]))
>> (s/fdef update! :args (s/cat ::field-map ::field-options) ...)
>> (defn update! [field-map] ... (:job-type field-map) ...)
>>
>> So far, so good. I have a parameter 'field-map' that can take optional
>> map keys, validate map arguments if the testing instrumentation is enabled,
>> etc.
>>
>> Here is my problem.  There appears to be no way for me to define, in this
>> namespace, map specs with a :job-type key, but that will have
>> :coercible-job-type semantics,
>> for my update! function. Or at least I don't see an easy way short of
>> writing a function to do everything that the existing machinery is doing
>> with respect to key and value validation,
>> which is a lot of work to handle this tiny thing, basically the ability
>> to have map keys and spec semantics bound to different names in s/keys
>> specs.
>>
>> For example, the following pseudo-spec might let me define a map key
>> :job-type whose semantics were specified by the ::coercible-job-type
>> definition.
>> Or inlining of definitions which the spec guide says was omitted on
>> purpose.
>>
>> (s/def ::field-map (s/keys :opt-un [... [::coercible-job-type :as ::job-
>> type]]))
>>
>> I want the map key to be ":job-type", but the clojure.spec semantics for
>> that field, *in selective module definitions*, to have ::coercible-job-type
>> behavior.
>>
>> So... am I missing something?
>>
>> --
> 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 a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/
> topic/clojure/ioR4875rRxU/unsubscribe.
> To unsubscribe from this group and all its topics, 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

Re: clojure.spec s/keys map key with alternative definitions in same namespace

2017-02-07 Thread Alex Miller
Spec names are intended to have enduring global semantics. So the notion of 
the same spec name having different semantics at different times seems to 
be at odds with that.

In general, it's often helpful to think about all the possible values that 
an attribute will have - that's the true spec. In this case, it seems like 
what you have for ::coercible-job-type is the true spec - it can be either 
a string or other named value.

And then think about the places where you need to add additional 
constraints to your ::job-record spec to narrow it. Like maybe here:

(s/fdef ... :ret (s/and ::job-record #(-> % ::job-type string?)))

You're on the brink of suggesting subtypes and covariant / contravariants, 
etc and that's a path spec is not going down. 


On Tuesday, February 7, 2017 at 9:40:24 AM UTC-6, Dave Tenny wrote:
>
> Let's say I have these definitions for a "job" record I'm managing, 
> perhaps in a database.
>
> (s/def ::job-status #{:in-progress :completed})
> (s/def ::user-id (s/and integer? #(>= % 0)))
> (s/def ::job-id integer?)
>
> (s/def ::coercible-job-type (s/and named? #(not (empty? (name %)
> (s/def ::job-type (s/and string? #(not (empty? %
>
> So we have a job status which can be any of a limited set of keywords,
> integer user and job ID's.  
>
> Then there's job type and my issue.  Depending on the context I want 
> either to insist that job type will be purely a non-empty string, or that 
> it may also be a 'named?' object, 
> i.e. something for which the clojure.core/name function will work.
>
> If I'm just returning a pure job record, my definition would look like 
> this:
>
> (s/def ::job-record 
>   (s/keys :req-un [::job-id ::user-id ::job-type ::job-status]))
>
> So a map with all those keys and type definitions. And that's great.  I 
> define functions that return these
> maps and so there's an (s/fdef ... :ret ::job-record).
>
> Now let's say I have an update! function that can take a map of optional 
> fields and update the record in the database with the fields that were 
> specified.
>
> (s/def ::field-options (s/keys :opt-un [::job-id ::user-id ::job-type 
> ::job-status]))
> (s/fdef update! :args (s/cat ::field-map ::field-options) ...)
> (defn update! [field-map] ... (:job-type field-map) ...)
>
> So far, so good. I have a parameter 'field-map' that can take optional map 
> keys, validate map arguments if the testing instrumentation is enabled, etc.
>
> Here is my problem.  There appears to be no way for me to define, in this 
> namespace, map specs with a :job-type key, but that will have 
> :coercible-job-type semantics,
> for my update! function. Or at least I don't see an easy way short of 
> writing a function to do everything that the existing machinery is doing 
> with respect to key and value validation,
> which is a lot of work to handle this tiny thing, basically the ability to 
> have map keys and spec semantics bound to different names in s/keys specs.
>
> For example, the following pseudo-spec might let me define a map key 
> :job-type whose semantics were specified by the ::coercible-job-type 
> definition.
> Or inlining of definitions which the spec guide says was omitted on 
> purpose.
>
> (s/def ::field-map (s/keys :opt-un [... [::coercible-job-type :as ::job-
> type]]))
>
> I want the map key to be ":job-type", but the clojure.spec semantics for 
> that field, *in selective module definitions*, to have ::coercible-job-type 
> behavior.
>
> So... am I missing something?
>
>

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


Re: Clojure.spec, maps, restrict valid keywords, easier way?

2017-02-07 Thread Erik Assum
Bruce Hauman has done some work in this area both in figwheel and in a branch 
of leiningen. 

Basically, if I understand correctly, he looks for misspelled keywords in 
configuration maps by taking the levenstein distance between expected, valid, 
keywords and non-matching keywords in the configuration. 

Erik. 
-- 
i farta

> Den 4. feb. 2017 kl. 12.48 skrev Dave Tenny :
> 
> I have found eastwood to be useful for a number of things, however on keyword 
> checking it failed terribly on our code base, though perhaps there have been 
> updates since I last tried it.
> 
> Thanks for the suggestion though.
> 
>> On Friday, February 3, 2017 at 7:26:01 PM UTC-5, Ben Brinckerhoff wrote:
>> The eastwood linter can also be configured to look for possibly misspelled 
>> keyword typos
>> 
>> https://github.com/jonase/eastwood#keyword-typos
 
> 
> -- 
> 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.


Re: Clojure.spec, maps, restrict valid keywords, easier way?

2017-02-04 Thread Dave Tenny
I have found eastwood to be useful for a number of things, however on 
keyword checking it failed terribly on our code base, though perhaps there 
have been updates since I last tried it.

Thanks for the suggestion though.

On Friday, February 3, 2017 at 7:26:01 PM UTC-5, Ben Brinckerhoff wrote:
>
> The eastwood linter can also be configured to look for possibly misspelled 
> keyword typos
>
> https://github.com/jonase/eastwood#keyword-typos
>
>>
>>>

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


Re: Clojure.spec, maps, restrict valid keywords, easier way?

2017-02-04 Thread Colin Fleming
I'm actually planning to do exactly that in Cursive, and it's more or less
what Eastwood does too per the link Ben posted.

On 4 February 2017 at 14:23, Linus Ericsson 
wrote:

> It would be great if an editor highlighted a (possibly qualified) keyword
> that was used only in that particular place (given all code loaded). This
> wouldn't be bullet-proof, but would have highlighted mistakes like
> :encypted (but could still confuse :encrypted? with :encrypted, and
> whatnot).
>
> /Linus
>
> On Friday, February 3, 2017 at 1:49:20 AM UTC+1, tbc++ wrote:
>>
>> A good editor should auto-complete your keywords for you. Since using
>> this feature in Cursive (same sort of thing is available in other editors)
>> the cases where I've mis-spelled a keyword have dropped dramatically. It's
>> a lot harder to mis-spell a keyword when you can just do: :egg/th
>> and the rest is auto-filled.
>>
>> On Thu, Feb 2, 2017 at 5:37 PM, Alex Miller  wrote:
>>
>>> Ugh, don't do that. Introducing layers that add no value is a bad idea.
>>> Just use the keyword directly.
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>
>>
>> --
>> “One of the main causes of the fall of the Roman Empire was that–lacking
>> zero–they had no way to indicate successful termination of their C
>> programs.”
>> (Robert Firth)
>>
> --
> 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.


Re: Clojure.spec, maps, restrict valid keywords, easier way?

2017-02-03 Thread Linus Ericsson
It would be great if an editor highlighted a (possibly qualified) keyword 
that was used only in that particular place (given all code loaded). This 
wouldn't be bullet-proof, but would have highlighted mistakes like 
:encypted (but could still confuse :encrypted? with :encrypted, and 
whatnot).

/Linus

On Friday, February 3, 2017 at 1:49:20 AM UTC+1, tbc++ wrote:
>
> A good editor should auto-complete your keywords for you. Since using this 
> feature in Cursive (same sort of thing is available in other editors) the 
> cases where I've mis-spelled a keyword have dropped dramatically. It's a 
> lot harder to mis-spell a keyword when you can just do: :egg/th and 
> the rest is auto-filled. 
>
> On Thu, Feb 2, 2017 at 5:37 PM, Alex Miller  > wrote:
>
>> Ugh, don't do that. Introducing layers that add no value is a bad idea. 
>> Just use the keyword directly.
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
>
> -- 
> “One of the main causes of the fall of the Roman Empire was that–lacking 
> zero–they had no way to indicate successful termination of their C 
> programs.”
> (Robert Firth) 
>

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


Re: Clojure.spec, maps, restrict valid keywords, easier way?

2017-02-03 Thread Ben Brinckerhoff
The eastwood linter can also be configured to look for possibly misspelled 
keyword typos

https://github.com/jonase/eastwood#keyword-typos

On Friday, February 3, 2017 at 3:47:21 AM UTC-7, John Schmidt wrote:
>
> I suggest something like (defn fetch-encrypted [] (fetch-important-data 
> {:encrypt true})) + unit tests
>
> On Friday, February 3, 2017 at 2:56:34 AM UTC+1, Michael Gardner wrote:
>>
>> What would be the Right Way to deal with typos like (fetch-important-data 
>> {:encypt true}), where the :encrypt key is optional? Timothy mentions 
>> auto-complete, which is better than nothing but doesn't feel like a real 
>> solution (especially to those who don't use auto-complete). 
>>
>> > On Feb 2, 2017, at 16:37, Alex Miller  wrote: 
>> > 
>> > Ugh, don't do that. Introducing layers that add no value is a bad idea. 
>> Just use the keyword directly. 
>> > 
>> > -- 
>> > You received this message because you are subscribed to the Google 
>> > Groups "Clojure" group. 
>> > To post to this group, send email to clo...@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+u...@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+u...@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.


Re: Clojure.spec, maps, restrict valid keywords, easier way?

2017-02-03 Thread John Schmidt
I suggest something like (defn fetch-encrypted [] (fetch-important-data 
{:encrypt true})) + unit tests

On Friday, February 3, 2017 at 2:56:34 AM UTC+1, Michael Gardner wrote:
>
> What would be the Right Way to deal with typos like (fetch-important-data 
> {:encypt true}), where the :encrypt key is optional? Timothy mentions 
> auto-complete, which is better than nothing but doesn't feel like a real 
> solution (especially to those who don't use auto-complete). 
>
> > On Feb 2, 2017, at 16:37, Alex Miller  > wrote: 
> > 
> > Ugh, don't do that. Introducing layers that add no value is a bad idea. 
> Just use the keyword directly. 
> > 
> > -- 
> > You received this message because you are subscribed to the Google 
> > Groups "Clojure" group. 
> > To post to this group, send email to clo...@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+u...@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+u...@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.


Re: Clojure.spec, maps, restrict valid keywords, easier way?

2017-02-02 Thread Michael Gardner
What would be the Right Way to deal with typos like (fetch-important-data 
{:encypt true}), where the :encrypt key is optional? Timothy mentions 
auto-complete, which is better than nothing but doesn't feel like a real 
solution (especially to those who don't use auto-complete).

> On Feb 2, 2017, at 16:37, Alex Miller  wrote:
> 
> Ugh, don't do that. Introducing layers that add no value is a bad idea. Just 
> use the keyword directly. 
> 
> -- 
> 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.


Re: Clojure.spec, maps, restrict valid keywords, easier way?

2017-02-02 Thread Timothy Baldridge
A good editor should auto-complete your keywords for you. Since using this
feature in Cursive (same sort of thing is available in other editors) the
cases where I've mis-spelled a keyword have dropped dramatically. It's a
lot harder to mis-spell a keyword when you can just do: :egg/th and
the rest is auto-filled.

On Thu, Feb 2, 2017 at 5:37 PM, Alex Miller  wrote:

> Ugh, don't do that. Introducing layers that add no value is a bad idea.
> Just use the keyword directly.
>
> --
> 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.
>



-- 
“One of the main causes of the fall of the Roman Empire was that–lacking
zero–they had no way to indicate successful termination of their C
programs.”
(Robert Firth)

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


Re: Clojure.spec, maps, restrict valid keywords, easier way?

2017-02-02 Thread Alex Miller
Ugh, don't do that. Introducing layers that add no value is a bad idea. Just 
use the keyword directly. 

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


Re: Clojure.spec, maps, restrict valid keywords, easier way?

2017-02-02 Thread Matching Socks
Keyword literals are inherently misspellable and trying to solve that 
problem with Spec does not really hit the nail on the head. But there is a 
solution: You do not have to use keyword literals very much!  

Instead of using, say, :egg/thunder throughout your program, def a var as 
:egg/thunder and then use the var.  Misspell the var and the compiler will 
bark at you.  If the var is egg/thunder then every part of the program can 
use it with not much loss of readability.  

If you mark the var as const, is it as efficient too as the keyword literal?

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


Re: Clojure.spec, maps, restrict valid keywords, easier way?

2017-02-02 Thread Mikhail Gusarov

Hello Alex,

The idea is (as I understand it) that every function should accept any
map and pick keys which it understands. If some keys are critical, then
they should be marked as such in the spec.

Function might iterate over keys and raise an error if there are keys
which belong to the namespace function cares about, but the names are
not known, but it is outside of spec's functionality and ought to be
done manually.

Best regards,
Mikhail.

On 2 Feb 2017, at 18:27, Dave Tenny wrote:


On Thursday, February 2, 2017 at 10:07:31 AM UTC-5, Alex Miller wrote:


We don't encourage you to do this, but I don't have an easier 
solution

than this.



Yes, and from the general standpoint of map handling I understand 
that.


From the standpoint of functions that take options and don't pass 
option
maps through to other functions, I disagree with the clojure 
philosophy
here.  So many bugs could be caught if we flagged unexpected map keys 
when
they're used as options to functions.  Of course use and validation 
via

clojure.spec helps too, but from a general bug catching standpoint I
believe there's a huge value to flagging inputs to functions that 
aren't

recognized by the functions.

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


Re: Clojure.spec, maps, restrict valid keywords, easier way?

2017-02-02 Thread Dave Tenny
On Thursday, February 2, 2017 at 10:07:31 AM UTC-5, Alex Miller wrote:
>
> We don't encourage you to do this, but I don't have an easier solution 
> than this.
>

Yes, and from the general standpoint of map handling I understand that.

>From the standpoint of functions that take options and don't pass option 
maps through to other functions, I disagree with the clojure philosophy 
here.  So many bugs could be caught if we flagged unexpected map keys when 
they're used as options to functions.  Of course use and validation via 
clojure.spec helps too, but from a general bug catching standpoint I 
believe there's a huge value to flagging inputs to functions that aren't 
recognized by the functions. 

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


Re: Clojure.spec, maps, restrict valid keywords, easier way?

2017-02-02 Thread Alex Miller
We don't encourage you to do this, but I don't have an easier solution than 
this.

On Thursday, February 2, 2017 at 7:05:37 AM UTC-6, Dave Tenny wrote:
>
> I want to specify in clojure spec that only declared keywords are 
> permitted in function calls.
> This is to catch what are usually mis-spelled or mis-cased keywors passed 
> via option maps in function calls.
>
> In the fdefs below, the second fdef will catch an invalid call, e.g. 
> (f 1 {:a 2 :B 3})
> but the first fdef will not.
>
> Is there an easier way to specify the more restrictive spec without having 
> to add my own 'every' and enumeration of the keys?
> (or build my own version of s/keys that does this automatically, which I'm 
> guessing is the answer).
>
> (require '[clojure.spec :as s])
> (require '[clojure.spec.test :as stest])
>
>
> (s/def ::x (fn [x] true))   ;for lack of any?
>
>
> ;; Will not catch invalid keywords
> (s/fdef f
>   :args (s/cat :x ::x
>:options (s/keys :opt-un [::a ::b]))
>   :ret nil?)
>
>
> ;; Will catch invalid keywords, but is there an easier way?
> (s/fdef f
>   :args (s/cat :x ::x
>:options (s/and (s/keys :opt-un [::a ::b])
>#(every? #{:a :b} (keys %
>   :ret nil?)
>
>
> (defn f [x {:keys [a b]}])
>
>
> (stest/instrument `f)
>
>
>
>
>
>

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


Re: clojure.spec: behaviour of ? macro

2017-01-28 Thread Marc Wilhelm Küster
Hi Leon,

thanks a lot for your explanation that a "regex-op outside of a regex-op 
always specs a collection". Then the behaviour is indeed clear

Best regards

Marc

Am Sonntag, 29. Januar 2017 00:32:14 UTC+1 schrieb Leon Grapenthin:
>
> Hi Marc, 
>
>  note that the return of gen/sample is 10 examples. Each one is a 
> collection.
>
> So the collection [] matches your spec, as does [:c]. And so on.
>
> A regex-op outside of a regex-op always specs a collection. If used within 
> another regex-op, it just specs an element.
>
> To illustrate:
> (gen/sample (s/gen (s/cat :kw (s/? #{:a :b :c :d})) :num number?))
>
> ((-2.0) (:a -3.0) (0) (1) (-2.625) (:a -1) (:d -1.5625) (0.75) (:a -24) 
> (:d -22))
>
>
> Kind regards,
>  Leon.
> On Saturday, January 28, 2017 at 6:29:39 PM UTC+1, Marc Wilhelm Küster 
> wrote:
>>
>> Good afternoon,
>>
>> like obviously quite a few others on this list I am looking into the 
>> upcoming (and IMHO absolutely great) clojure.spec 
>> During this I noted that the  ? macro seems to behave differently from 
>> what I would have naively expected from its documentation (cf. 
>> https://clojure.github.io/clojure/branch-master/clojure.spec-api.html#clojure.spec/?
>> ):
>>
>> ? macro
>>
>> Usage: (? pred-form)
>>
>> Returns a regex op that matches zero or one value matching
>> pred. Produces a single value (not a collection) if matched.
>>
>>
>> In contract, with the namespaces set to 
>> [clojure.spec :as s]
>> [clojure.spec.gen :as gen]
>>
>> the following snippet
>>
>> (s/def ::abcd #{:a :b :c :d})
>> (gen/sample (s/gen (s/? ::abcd)))
>>
>> returns a collection of collections:
>> ([] [:c] [:d] [:b] [:b] [] [:a] [] [:d] [])
>>
>> I would have expected to find either the value itself or nothing, a 
>> behaviour that would seem to me also more practical when composing larger 
>> records with optional elements. However, I might be misreading the 
>> documentation and would be grateful for any clarification
>>
>> Best regards,
>>
>> Marc
>>
>>

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


Re: clojure.spec: behaviour of ? macro

2017-01-28 Thread Leon Grapenthin
Hi Marc, 

 note that the return of gen/sample is 10 examples. Each one is a 
collection.

So the collection [] matches your spec, as does [:c]. And so on.

A regex-op outside of a regex-op always specs a collection. If used within 
another regex-op, it just specs an element.

To illustrate:
(gen/sample (s/gen (s/cat :kw (s/? #{:a :b :c :d})) :num number?))

((-2.0) (:a -3.0) (0) (1) (-2.625) (:a -1) (:d -1.5625) (0.75) (:a -24) (:d 
-22))


Kind regards,
 Leon.
On Saturday, January 28, 2017 at 6:29:39 PM UTC+1, Marc Wilhelm Küster 
wrote:
>
> Good afternoon,
>
> like obviously quite a few others on this list I am looking into the 
> upcoming (and IMHO absolutely great) clojure.spec 
> During this I noted that the  ? macro seems to behave differently from 
> what I would have naively expected from its documentation (cf. 
> https://clojure.github.io/clojure/branch-master/clojure.spec-api.html#clojure.spec/?
> ):
>
> ? macro
>
> Usage: (? pred-form)
>
> Returns a regex op that matches zero or one value matching
> pred. Produces a single value (not a collection) if matched.
>
>
> In contract, with the namespaces set to 
> [clojure.spec :as s]
> [clojure.spec.gen :as gen]
>
> the following snippet
>
> (s/def ::abcd #{:a :b :c :d})
> (gen/sample (s/gen (s/? ::abcd)))
>
> returns a collection of collections:
> ([] [:c] [:d] [:b] [:b] [] [:a] [] [:d] [])
>
> I would have expected to find either the value itself or nothing, a 
> behaviour that would seem to me also more practical when composing larger 
> records with optional elements. However, I might be misreading the 
> documentation and would be grateful for any clarification
>
> Best regards,
>
> Marc
>
>

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


Re: clojure.spec bug?

2017-01-02 Thread John Schmidt
No worries! Big thanks for digging into this, I saw your update on the JIRA 
as well and it certainly seems like you've found the likely culprit.

On Monday, January 2, 2017 at 4:47:53 PM UTC+1, miner wrote:
>
>
> On Jan 1, 2017, at 7:13 PM, John Schmidt  > wrote:
>
> Steve: both ::game3 and ::game4 from your suggestions result in the same 
> error.
>
>
> Sorry for my mistaken conjecture.  My issue with the macroexpansion looks 
> like a red herring.  I guess I confused myself with quick tests in the 
> REPL. 
>
> The problem seems to be sensitive to the order of the declaration of the 
> predicates versus the protocol extension.  That is, it seems to work for me 
> if I do the extend-type Foo before defining the predicates that refer to 
> the protocol.  I probably did this accidentally while playing in the REPL. 
>
> So now I think the issue is that one version of the protocol was captured 
> by the “early" predicates, and then the protocol itself was changed so 
> references to the “old” protocol (with the same name) no longer worked.
>
> The #(…) closure seems to do the right thing as the protocol symbol 
> doesn’t get evaluated at definition time.
>
>

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


Re: clojure.spec bug?

2017-01-02 Thread Steve Miner

> On Jan 1, 2017, at 7:13 PM, John Schmidt  wrote:
> 
> Steve: both ::game3 and ::game4 from your suggestions result in the same 
> error.
> 

Sorry for my mistaken conjecture.  My issue with the macroexpansion looks like 
a red herring.  I guess I confused myself with quick tests in the REPL. 

The problem seems to be sensitive to the order of the declaration of the 
predicates versus the protocol extension.  That is, it seems to work for me if 
I do the extend-type Foo before defining the predicates that refer to the 
protocol.  I probably did this accidentally while playing in the REPL. 

So now I think the issue is that one version of the protocol was captured by 
the “early" predicates, and then the protocol itself was changed so references 
to the “old” protocol (with the same name) no longer worked.

The #(…) closure seems to do the right thing as the protocol symbol doesn’t get 
evaluated at definition time.

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


Re: clojure.spec bug?

2017-01-01 Thread John Schmidt
JIRA filed: http://dev.clojure.org/jira/browse/CLJ-2094.

Steve: both ::game3 and ::game4 from your suggestions result in the same 
error.

On Saturday, December 31, 2016 at 5:44:47 PM UTC+1, Alex Miller wrote:
>
> You can file a jira on this.
>
> On Saturday, December 31, 2016 at 10:16:00 AM UTC-6, miner wrote:
>>
>>
>> On Dec 30, 2016, at 9:42 AM, John Schmidt > > wrote:
>>
>> (s/def ::game1 #(satisfies? Game %))
>> (s/def ::game2 (partial satisfies? Game))
>>
>>
>> (s/explain ::game2 (spec-test.foo/->Foo))
>> val: #spec_test.foo.Foo{} fails spec: :spec-test.core/game2 predicate: 
>> (partial satisfies? Game) < WAT
>> nil
>>
>>
>> It looks like the spec macros aren’t resolving the Game reference in the 
>> game2 spec.  You can use macroexpand-1 to see what was happening at the 
>> top-level.  The internal macros get a little complicated so I can’t say if 
>> code expressions like this were intended to work.  It doesn’t hurt to file 
>> a bug.
>>
>> I think the usual way to write this would be to define your own little 
>> predicate first and then use that var in the spec.
>>
>> (def my-game? (partial satisfies? Game))
>>
>> (s/def ::game3 my-game?)
>>
>> If you want to work around the immediate issue, try using the fully 
>> qualified symbol for the protocol.  (I prefer ::game3 FWIW.)
>>
>> (s/def ::game4 (partial satisfies? spec-test.core/Game))
>>
>>
>>
>>
>>
>>
>>

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


Re: clojure.spec bug?

2016-12-31 Thread Alex Miller
You can file a jira on this.

On Saturday, December 31, 2016 at 10:16:00 AM UTC-6, miner wrote:
>
>
> On Dec 30, 2016, at 9:42 AM, John Schmidt  
> wrote:
>
> (s/def ::game1 #(satisfies? Game %))
> (s/def ::game2 (partial satisfies? Game))
>
>
> (s/explain ::game2 (spec-test.foo/->Foo))
> val: #spec_test.foo.Foo{} fails spec: :spec-test.core/game2 predicate: 
> (partial satisfies? Game) < WAT
> nil
>
>
> It looks like the spec macros aren’t resolving the Game reference in the 
> game2 spec.  You can use macroexpand-1 to see what was happening at the 
> top-level.  The internal macros get a little complicated so I can’t say if 
> code expressions like this were intended to work.  It doesn’t hurt to file 
> a bug.
>
> I think the usual way to write this would be to define your own little 
> predicate first and then use that var in the spec.
>
> (def my-game? (partial satisfies? Game))
>
> (s/def ::game3 my-game?)
>
> If you want to work around the immediate issue, try using the fully 
> qualified symbol for the protocol.  (I prefer ::game3 FWIW.)
>
> (s/def ::game4 (partial satisfies? spec-test.core/Game))
>
>
>
>
>
>
>

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


Re: clojure.spec bug?

2016-12-31 Thread Steve Miner

> On Dec 30, 2016, at 9:42 AM, John Schmidt  wrote:
> 
> (s/def ::game1 #(satisfies? Game %))
> (s/def ::game2 (partial satisfies? Game))
> 
> (s/explain ::game2 (spec-test.foo/->Foo))
> val: #spec_test.foo.Foo{} fails spec: :spec-test.core/game2 predicate: 
> (partial satisfies? Game) < WAT
> nil

It looks like the spec macros aren’t resolving the Game reference in the game2 
spec.  You can use macroexpand-1 to see what was happening at the top-level.  
The internal macros get a little complicated so I can’t say if code expressions 
like this were intended to work.  It doesn’t hurt to file a bug.

I think the usual way to write this would be to define your own little 
predicate first and then use that var in the spec.

(def my-game? (partial satisfies? Game))

(s/def ::game3 my-game?)

If you want to work around the immediate issue, try using the fully qualified 
symbol for the protocol.  (I prefer ::game3 FWIW.)

(s/def ::game4 (partial satisfies? spec-test.core/Game))






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


Re: clojure.spec bug?

2016-12-30 Thread Sean Corfield
Sorry, I read your original email on my phone and misread part of your code 
(thinking I’d seen an `instrument` call in there), so I thought it was the 
problem with instrumentation breaking (some) protocol-based functions.

 

Now I look at this on the big screen, I realize my mistake.

 

I agree that this does look very odd. I’ll be interested to hear an explanation 
for why (partial satisfies? Game) and #(satisfies? Game %) are not equivalent 
in this context.

 

Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN
An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood

 

On 12/30/16, 4:16 PM, "John Schmidt"  wrote:

 

Thanks for the reply Sean.

 

Could you explain a bit more why/how this is the same issue? The ticket seems 
to revolve around instrumentation and results in exceptions, not validation 
failures. And if the issue is with protocol functions, how come the ::game1 
spec works while the ::game2 spec doesn't?

On Friday, December 30, 2016 at 11:24:30 PM UTC+1, Sean Corfield wrote:

See http://dev.clojure.org/jira/browse/CLJ-1941 (in particular, the comments 
about protocols)

 

Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN
An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood

 

On 12/30/16, 6:42 AM, "John Schmidt"  wrote:

 

Hello folks!

 

I have the following two clj files (I've tried to come up with a minimal 
example):

 

core.clj

--

(ns spec-test.core
  (:require [clojure.spec :as s]))
 
(defprotocol Game
  (move [game]))
 
(s/def ::game1 #(satisfies? Game %))
(s/def ::game2 (partial satisfies? Game))
foo.clj

--

(ns spec-test.foo
  (:require [spec-test.core :refer [Game]]))
 
(defrecord Foo [])
 
(extend-type Foo
  Game
  (move [game]))
 
 
 
Here's a REPL session that explains my problem:
 
➜  spec-test lein repl
WARNING: boolean? already refers to: #'clojure.core/boolean? in namespace: 
cider.inlined-deps.fipp.v0v6v4.fipp.visit, being replaced by: 
#'cider.inlined-deps.fipp.v0v6v4.fipp.visit/boolean?
nREPL server started on port 58606 on host 127.0.0.1 - nrepl://127.0.0.1:58606
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.9.0-alpha14
Java HotSpot(TM) 64-Bit Server VM 1.8.0_92-b14
Docs: (doc function-name-here)
  (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e
 
user=> (ns spec-test.core)
nil
spec-test.core=> (require 'spec-test.core :reload)
nil
spec-test.core=> (require 'spec-test.foo :reload)
nil
spec-test.core=> (satisfies? Game (spec-test.foo/->Foo))
true
spec-test.core=> ((partial satisfies? Game) (spec-test.foo/->Foo))
true
spec-test.core=> (s/explain ::game1 (spec-test.foo/->Foo))
Success!
nil
spec-test.core=> (s/explain ::game2 (spec-test.foo/->Foo))
val: #spec_test.foo.Foo{} fails spec: :spec-test.core/game2 predicate: (partial 
satisfies? Game) < WAT
nil
 
I have no idea what is going on here, but it seems the `extend-type` is 
important. If I inline the Game protocol implementation in the defrecord, it 
works.
 
Any ideas?
 
Thanks,
John
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@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+u...@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 

Re: clojure.spec bug?

2016-12-30 Thread John Schmidt
Thanks for the reply Sean.

Could you explain a bit more why/how this is the same issue? The ticket 
seems to revolve around instrumentation and results in exceptions, not 
validation failures. And if the issue is with protocol functions, how come 
the ::game1 spec works while the ::game2 spec doesn't?

On Friday, December 30, 2016 at 11:24:30 PM UTC+1, Sean Corfield wrote:
>
> See http://dev.clojure.org/jira/browse/CLJ-1941 (in particular, the 
> comments about protocols)
>
>  
>
> Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN
> An Architect's View -- http://corfield.org/
>
> "If you're not annoying somebody, you're not really alive."
> -- Margaret Atwood
>
>  
>
> On 12/30/16, 6:42 AM, "John Schmidt"   on behalf of john.sc...@gmail.com > wrote:
>
>  
>
> Hello folks!
>
>  
>
> I have the following two clj files (I've tried to come up with a minimal 
> example):
>
>  
>
> core.clj
>
> --
>
> (ns spec-test.core
>
>   (:require [clojure.spec :as s]))
>
>  
>
> (defprotocol Game
>
>   (move [game]))
>
>  
>
> (s/def ::game1 #(satisfies? Game %))
>
> (s/def ::game2 (partial satisfies? Game))
>
> foo.clj
>
> --
>
> (ns spec-test.foo
>
>   (:require [spec-test.core :refer [Game]]))
>
>  
>
> (defrecord Foo [])
>
>  
>
> (extend-type Foo
>
>   Game
>
>   (move [game]))
>
>  
>
>  
>
>  
>
> Here's a REPL session that explains my problem:
>
>  
>
> ➜  spec-test lein repl
>
> WARNING: boolean? already refers to: #'clojure.core/boolean? in namespace: 
> cider.inlined-deps.fipp.v0v6v4.fipp.visit, being replaced by: 
> #'cider.inlined-deps.fipp.v0v6v4.fipp.visit/boolean?
>
> nREPL server started on port 58606 on host 127.0.0.1 - nrepl://127.0.0.1:58606
>
> REPL-y 0.3.7, nREPL 0.2.12
>
> Clojure 1.9.0-alpha14
>
> Java HotSpot(TM) 64-Bit Server VM 1.8.0_92-b14
>
> Docs: (doc function-name-here)
>
>   (find-doc "part-of-name-here")
>
>   Source: (source function-name-here)
>
>  Javadoc: (javadoc java-object-or-class-here)
>
> Exit: Control+D or (exit) or (quit)
>
>  Results: Stored in vars *1, *2, *3, an exception in *e
>
>  
>
> user=> (ns spec-test.core)
>
> nil
>
> spec-test.core=> (require 'spec-test.core :reload)
>
> nil
>
> spec-test.core=> (require 'spec-test.foo :reload)
>
> nil
>
> spec-test.core=> (satisfies? Game (spec-test.foo/->Foo))
>
> true
>
> spec-test.core=> ((partial satisfies? Game) (spec-test.foo/->Foo))
>
> true
>
> spec-test.core=> (s/explain ::game1 (spec-test.foo/->Foo))
>
> Success!
>
> nil
>
> spec-test.core=> (s/explain ::game2 (spec-test.foo/->Foo))
>
> val: #spec_test.foo.Foo{} fails spec: :spec-test.core/game2 predicate: 
> (partial satisfies? Game) < WAT
>
> nil
>
>  
>
> I have no idea what is going on here, but it seems the `extend-type` is 
> important. If I inline the Game protocol implementation in the defrecord, it 
> works.
>
>  
>
> Any ideas?
>
>  
>
> Thanks,
>
> John
>
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@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+u...@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+u...@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.


Re: clojure.spec bug?

2016-12-30 Thread Sean Corfield
See http://dev.clojure.org/jira/browse/CLJ-1941 (in particular, the comments 
about protocols)

 

Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN
An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood

 

On 12/30/16, 6:42 AM, "John Schmidt"  wrote:

 

Hello folks!

 

I have the following two clj files (I've tried to come up with a minimal 
example):

 

core.clj

--

(ns spec-test.core
  (:require [clojure.spec :as s]))
 
(defprotocol Game
  (move [game]))
 
(s/def ::game1 #(satisfies? Game %))
(s/def ::game2 (partial satisfies? Game))
foo.clj

--

(ns spec-test.foo
  (:require [spec-test.core :refer [Game]]))
 
(defrecord Foo [])
 
(extend-type Foo
  Game
  (move [game]))
 
 
 
Here's a REPL session that explains my problem:
 
➜  spec-test lein repl
WARNING: boolean? already refers to: #'clojure.core/boolean? in namespace: 
cider.inlined-deps.fipp.v0v6v4.fipp.visit, being replaced by: 
#'cider.inlined-deps.fipp.v0v6v4.fipp.visit/boolean?
nREPL server started on port 58606 on host 127.0.0.1 - nrepl://127.0.0.1:58606
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.9.0-alpha14
Java HotSpot(TM) 64-Bit Server VM 1.8.0_92-b14
    Docs: (doc function-name-here)
  (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e
 
user=> (ns spec-test.core)
nil
spec-test.core=> (require 'spec-test.core :reload)
nil
spec-test.core=> (require 'spec-test.foo :reload)
nil
spec-test.core=> (satisfies? Game (spec-test.foo/->Foo))
true
spec-test.core=> ((partial satisfies? Game) (spec-test.foo/->Foo))
true
spec-test.core=> (s/explain ::game1 (spec-test.foo/->Foo))
Success!
nil
spec-test.core=> (s/explain ::game2 (spec-test.foo/->Foo))
val: #spec_test.foo.Foo{} fails spec: :spec-test.core/game2 predicate: (partial 
satisfies? Game) < WAT
nil
 
I have no idea what is going on here, but it seems the `extend-type` is 
important. If I inline the Game protocol implementation in the defrecord, it 
works.
 
Any ideas?
 
Thanks,
John
-- 
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.


Re: Clojure.spec - Why should you use and when

2016-12-11 Thread Patrick Kristiansen
Hi Rickesh

Take a look at this:

http://clojure.org/about/spec

-Patrick

On Sunday, December 11, 2016 at 5:30:19 PM UTC+1, Rickesh Bedia wrote:
>
> Hello,
>
> I have recently watched Rich Hickeys talk at Cojure Conj 2016 (
> https://www.youtube.com/watch?v=oyLBGkS5ICk - here's the link in case 
> anyone missed it) and although it was very interesting, I didn't really 
> understand the point in Clojure.Spec or when you'd use it. It seemed like 
> most of the ideas, such as conform, valid etc, had similar functions in 
> Clojure already.
>
> I have only been learning clojure for around 3 months now so maybe this is 
> due to lack of programming/Clojure experience.
>
> Thanks
>

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


Re: clojure.spec - seeking a working example of stest/instrument with the :replace option

2016-11-08 Thread Joseph Wayne Norton
Alex -

Perfect.  Thank you for the clarification.  I wasn’t sure from the 
documentation.

Specs for functions in spec would be really helpful.

Thank you very much.



> On Nov 8, 2016, at 08:59, Alex Miller  wrote:
> 
> The issue is in the call to instrument:
> 
>  (stest/instrument `ranged-rand {:replace {`ranged-rand ::ranged-const}})
> 
> The :replace map is "a map from var-name symbols to replacement fns". Here, 
> you are passing a spec name, rather than a function. So you want something 
> like this instead:
> 
>  (stest/instrument `ranged-rand {:replace {`ranged-rand ranged-const}})
> 
> 
> 
> On Monday, November 7, 2016 at 10:07:39 PM UTC-6, Joseph Wayne Norton wrote:
> Hello.
> 
> I tried to construct a small example to understand and to illustrate how 
> stest/instrument with the :replace option works.
> 
> My attempt to construct a small working example was to expand on the 
> ranged-rand example in the clojure.spec Guide.
> 
> I created another function called ranged-const that always returns the value 
> of the start argument.  I wanted to see if the ranged-const function could 
> become a mock to the ranged-rand function.
> 
> Here is the behavior that I am seeing.  The mocked ranged-rand should be 
> returning 2 but it always returns 5 instead.  Secondly, I would have expected 
> to see the printed side-effect of [:ranged-const 2 5].
> 
> 
> spec-demo.core=> (stest/instrument `ranged-rand {:replace {`ranged-rand 
> ::ranged-const}})
> [spec-demo.core/ranged-rand]
> spec-demo.core=> (ranged-const 2 5)
> [:ranged-const 2 5]
> 2
> spec-demo.core=> (ranged-rand 2 5)
> 5
> spec-demo.core=> (ranged-rand 2 5)
> 5
> 
> 
> Any suggestions?
> 
> Best regards,
> 
> Joe N.
> 
> 
> Here is a complete log:
> 
> $ cat .boot/boot.properties 
> #http://boot-clj.com 
> #Sat Sep 17 23:34:35 CDT 2016
> BOOT_EMIT_TARGET=no
> BOOT_CLOJURE_NAME=org.clojure/clojure
> BOOT_VERSION=2.6.0
> BOOT_CLOJURE_VERSION=1.9.0-alpha14
> 
> 
> $ boot repl
> nREPL server started on port 53962 on host 127.0.0.1 - 
> nrepl://127.0.0.1:53962 <>
> REPL-y 0.3.7, nREPL 0.2.12
> Clojure 1.9.0-alpha14
> Java HotSpot(TM) 64-Bit Server VM 1.8.0_102-b14
> Exit: Control+D or (exit) or (quit)
> Commands: (user/help)
> Docs: (doc function-name-here)
>   (find-doc "part-of-name-here")
> Find by Name: (find-name "part-of-name-here")
>   Source: (source function-name-here)
>  Javadoc: (javadoc java-object-or-class-here)
> Examples from clojuredocs.org : [clojuredocs or 
> cdoc]
>   (user/clojuredocs name-here)
>   (user/clojuredocs "ns-here" "name-here")
> boot.user=> (ns spec-demo.core
>#_=>   (:require [clojure.spec :as s]
>#_=> [clojure.spec.test :as stest])
>#_=>   (:gen-class))
> nil
> 
> 
> spec-demo.core=> (defn ranged-rand
> #_=>   "Returns random int in range start <= rand < end"
> #_=>   [start end]
> #_=>   (println [:ranged-rand start end]) ; DEBUG
> #_=>   (+ start (long (rand (- end start)
> #'spec-demo.core/ranged-rand 
> 
> spec-demo.core=> (s/fdef ranged-rand
> #_=> :args (s/and (s/cat :start int? :end int?)
> #_=>  #(< (:start %) (:end %)))
> #_=> :ret int?
> #_=> :fn (s/and #(>= (:ret %) (-> % :args :start))
> #_=>#(< (:ret %) (-> % :args :end
> spec-demo.core/ranged-rand
> 
> spec-demo.core=> (defn ranged-const
> #_=>   "Returns const int equal to start such that start <= const 
> < end"
> #_=>   [start end]
> #_=>   (println [:ranged-const start end]) ; DEBUG
> #_=>   start)
> #'spec-demo.core/ranged-const
> 
> spec-demo.core=> (s/fdef ranged-const
> #_=> :args (s/and (s/cat :start int? :end int?)
> #_=>  #(< (:start %) (:end %)))
> #_=> :ret int?
> #_=> :fn #(= (:ret %) (-> % :args :start)))
> spec-demo.core/ranged-const
> spec-demo.core=> (ranged-rand 2 5)
> [:ranged-rand 2 5]
> 3
> spec-demo.core=> (ranged-rand 2 5)
> [:ranged-rand 2 5]
> 4
> spec-demo.core=> (ranged-rand 2 5)
> [:ranged-rand 2 5]
> 2
> spec-demo.core=> (ranged-const 2 5)
> [:ranged-const 2 5]
> 2
> spec-demo.core=> (ranged-const 2 5)
> [:ranged-const 2 5]
> 2
> spec-demo.core=> (ranged-const 2 5)
> [:ranged-const 2 5]
> 2
> 
> spec-demo.core=> (stest/instrument `ranged-rand {:replace {`ranged-rand 
> ::ranged-const}})
> [spec-demo.core/ranged-rand]
> spec-demo.core=> (ranged-const 2 5)
> [:ranged-const 2 5]
> 2
> spec-demo.core=> (ranged-rand 2 5)
> 5
> spec-demo.core=> (ranged-rand 2 5)
> 5
> spec-demo.core=> (ranged-rand 2 5)
> 5
> spec-demo.core=> 
> 
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to 

Re: clojure.spec - seeking a working example of stest/instrument with the :replace option

2016-11-08 Thread Alex Miller
The issue is in the call to instrument:

 (stest/instrument `ranged-rand {:replace {`ranged-rand ::ranged-const}})

The :replace map is "a map from var-name symbols to replacement fns". Here, 
you are passing a spec name, rather than a function. So you want something 
like this instead:

 (stest/instrument `ranged-rand {:replace {`ranged-rand ranged-const}})



On Monday, November 7, 2016 at 10:07:39 PM UTC-6, Joseph Wayne Norton wrote:
>
> Hello.
>
> I tried to construct a small example to understand and to illustrate how 
> stest/instrument with the :replace option works.
>
> My attempt to construct a small working example was to expand on the 
> ranged-rand example in the clojure.spec Guide.
>
> I created another function called ranged-const that always returns the 
> value of the start argument.  I wanted to see if the ranged-const function 
> could become a mock to the ranged-rand function.
>
> Here is the behavior that I am seeing.  The mocked ranged-rand should be 
> returning 2 but it always returns 5 instead.  Secondly, I would have 
> expected to see the printed side-effect of [:ranged-const 2 5].
>
>
> spec-demo.core=> (stest/instrument `ranged-rand {:replace {`ranged-rand 
> ::ranged-const}})
> [spec-demo.core/ranged-rand]
> spec-demo.core=> (ranged-const 2 5)
> [:ranged-const 2 5]
> 2
> *spec-demo.core=> (ranged-rand 2 5)*
> *5*
> *spec-demo.core=> (ranged-rand 2 5)*
> *5*
>
>
> Any suggestions?
>
> Best regards,
>
> Joe N.
>
>
> Here is a complete log:
>
> $ cat .boot/boot.properties 
> #http://boot-clj.com
> #Sat Sep 17 23:34:35 CDT 2016
> BOOT_EMIT_TARGET=no
> BOOT_CLOJURE_NAME=org.clojure/clojure
> BOOT_VERSION=2.6.0
> BOOT_CLOJURE_VERSION=1.9.0-alpha14
>
>
> $ boot repl
> *nREPL server started on port 53962 on host 127.0.0.1 - 
> nrepl://127.0.0.1:53962*
> REPL-y 0.3.7, nREPL 0.2.12
> Clojure 1.9.0-alpha14
> Java HotSpot(TM) 64-Bit Server VM 1.8.0_102-b14
> Exit: Control+D or (exit) or (quit)
> Commands: (user/help)
> Docs: (doc function-name-here)
>   (find-doc "part-of-name-here")
> Find by Name: (find-name "part-of-name-here")
>   Source: (source function-name-here)
>  Javadoc: (javadoc java-object-or-class-here)
> Examples from clojuredocs.org: [clojuredocs or cdoc]
>   (user/clojuredocs name-here)
>   (user/clojuredocs "ns-here" "name-here")
> boot.user=> (ns spec-demo.core
>#_=>   (:require [clojure.spec :as s]
>#_=> [clojure.spec.test :as stest])
>#_=>   (:gen-class))
> nil
>
>
> spec-demo.core=> (defn ranged-rand
> #_=>   "Returns random int in range start <= rand < end"
> #_=>   [start end]
> #_=>   (println [:ranged-rand start end]) ; DEBUG
> #_=>   (+ start (long (rand (- end start)
> #'spec-demo.core/ranged-rand 
>
> spec-demo.core=> (s/fdef ranged-rand
> #_=> :args (s/and (s/cat :start int? :end int?)
> #_=>  #(< (:start %) (:end %)))
> #_=> :ret int?
> #_=> :fn (s/and #(>= (:ret %) (-> % :args :start))
> #_=>#(< (:ret %) (-> % :args :end
> spec-demo.core/ranged-rand
>
> spec-demo.core=> (defn ranged-const
> #_=>   "Returns const int equal to start such that start <= 
> const < end"
> #_=>   [start end]
> #_=>   (println [:ranged-const start end]) ; DEBUG
> #_=>   start)
> #'spec-demo.core/ranged-const
>
> spec-demo.core=> (s/fdef ranged-const
> #_=> :args (s/and (s/cat :start int? :end int?)
> #_=>  #(< (:start %) (:end %)))
> #_=> :ret int?
> #_=> :fn #(= (:ret %) (-> % :args :start)))
> spec-demo.core/ranged-const
> spec-demo.core=> (ranged-rand 2 5)
> [:ranged-rand 2 5]
> 3
> spec-demo.core=> (ranged-rand 2 5)
> [:ranged-rand 2 5]
> 4
> spec-demo.core=> (ranged-rand 2 5)
> [:ranged-rand 2 5]
> 2
> spec-demo.core=> (ranged-const 2 5)
> [:ranged-const 2 5]
> 2
> spec-demo.core=> (ranged-const 2 5)
> [:ranged-const 2 5]
> 2
> spec-demo.core=> (ranged-const 2 5)
> [:ranged-const 2 5]
> 2
>
> spec-demo.core=> (stest/instrument `ranged-rand {:replace {`ranged-rand 
> ::ranged-const}})
> [spec-demo.core/ranged-rand]
> spec-demo.core=> (ranged-const 2 5)
> [:ranged-const 2 5]
> 2
> spec-demo.core=> (ranged-rand 2 5)
> 5
> spec-demo.core=> (ranged-rand 2 5)
> 5
> spec-demo.core=> (ranged-rand 2 5)
> 5
> spec-demo.core=> 
>
>

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

Re: clojure.spec gen-testing VS NaN

2016-11-07 Thread dimitris

Alright cool, I'll do that tomorrow :)

Thanks,

Dimitris


On 07/11/16 22:07, Alex Miller wrote:
I think it would be reasonable to log a jira enhancement request for 
the spec any? generator to avoid generating double NaNs.



On Monday, November 7, 2016 at 12:30:24 PM UTC-6, Jim foo.bar wrote:

Hi Alex,

Oh yeah I've seen `s/double-in` but as you point out that doesn't
help me if I want to :ret spec a function with similar semantics
as remove (a fn that transforms a seq given a predicate), which I
find a very common indeed.  I'm only starting playing with
clojure.spec (in fact i've only spec'ed 2 fns so far) and I've not
yet had to spec specifically a double-precision number. I have had
however the need to spec :any? as ::anything-but-NaN, in both my
first 2 specs, so according to my experience this is by no means a
rare issue. In fact, looking at clojure.core, most fns operate on
seqs, and a good proportion of them processes/transforms a coll
according to a predicate/fn. This has nothing to do with doubles
or in fact numbers. We can only spec the contents of the
collection as `any?` right? anything more specific, and the
gen-surface area is reduced. So yeah it's great that we have
`s/double-in`, but ideally I'd also like a reliable way to say
that the output coll from a fn is equal to the input coll, while
having specified the contents of that coll with `any?`, and
without having to jump through hoops in the :ret spec. My
workaround is actually working nicely for me, and i can certainly
live without NaNs in the tests, but it still feels a bit hacky.

Thanks,

Dimitris


On 07/11/16 18:14, Alex Miller wrote:

Please also take a look at s/double-in, which allows you to
exclude NaN (and Infinity/-Infinity) as valid values.

(I realize this does not address the any? question, but that
seems like a rarer issue to me than cases where I'm explicitly
spec'ing a double but don't want to allow NaN.)

On Monday, November 7, 2016 at 11:37:08 AM UTC-6, Jim foo.bar wrote:

Hi all,

clojure.spec helped me realise that NaNs totally break [1]
equality (per
`clojure.core/=`). Even though in real production code this
might not be
an issue due to how infrequently one deals with NaNs, but during
gen-testing I've found them extremely annoying, and I've
essentially
worked around this by spec-ing things I'd normally specify
via `any?`,
via `(s/and any? (complement double-NaN?))` instead. I have
to do this
for any spec, where in the :ret spec i need to be able to
confirm that
the input coll is equal to the output coll (e.g.
`clojure.core/remove`
returns the same coll it was passed in when nothing has been
removed),
which is a possibility in a lot of functions. Have other people
encountered this as well, and if yes, how are you guys
dealing with it?
Thanks in advance...

Kind regards,

Dimitris

[1]: (= [:a Double/NaN] [:a Double/NaN]) => false



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

Re: clojure.spec gen-testing VS NaN

2016-11-07 Thread Alex Miller
I think it would be reasonable to log a jira enhancement request for the 
spec any? generator to avoid generating double NaNs.


On Monday, November 7, 2016 at 12:30:24 PM UTC-6, Jim foo.bar wrote:
>
> Hi Alex,
>
> Oh yeah I've seen `s/double-in` but as you point out that doesn't help me 
> if I want to :ret spec a function with similar semantics as remove (a fn 
> that transforms a seq given a predicate), which I find a very common 
> indeed.  I'm only starting playing with clojure.spec (in fact i've only 
> spec'ed 2 fns so far) and I've not yet had to spec specifically a 
> double-precision number. I have had however the need to spec :any? as 
> ::anything-but-NaN, in both my first 2 specs, so according to my experience 
> this is by no means a rare issue. In fact, looking at clojure.core, most 
> fns operate on seqs, and a good proportion of them processes/transforms a 
> coll according to a predicate/fn. This has nothing to do with doubles or in 
> fact numbers. We can only spec the contents of the collection as `any?` 
> right? anything more specific, and the gen-surface area is reduced. So yeah 
> it's great that we have `s/double-in`, but ideally I'd also like a reliable 
> way to say that the output coll from a fn is equal to the input coll, while 
> having specified the contents of that coll with `any?`, and without having 
> to jump through hoops in the :ret spec. My workaround is actually working 
> nicely for me, and i can certainly live without NaNs in the tests, but it 
> still feels a bit hacky.
>
> Thanks,
>
> Dimitris
>
> On 07/11/16 18:14, Alex Miller wrote:
>
> Please also take a look at s/double-in, which allows you to exclude NaN 
> (and Infinity/-Infinity) as valid values. 
>
> (I realize this does not address the any? question, but that seems like a 
> rarer issue to me than cases where I'm explicitly spec'ing a double but 
> don't want to allow NaN.)
>
> On Monday, November 7, 2016 at 11:37:08 AM UTC-6, Jim foo.bar wrote: 
>>
>> Hi all, 
>>
>> clojure.spec helped me realise that NaNs totally break [1] equality (per 
>> `clojure.core/=`). Even though in real production code this might not be 
>> an issue due to how infrequently one deals with NaNs, but during 
>> gen-testing I've found them extremely annoying, and I've essentially 
>> worked around this by spec-ing things I'd normally specify via `any?`, 
>> via `(s/and any? (complement double-NaN?))` instead. I have to do this 
>> for any spec, where in the :ret spec i need to be able to confirm that 
>> the input coll is equal to the output coll (e.g. `clojure.core/remove` 
>> returns the same coll it was passed in when nothing has been removed), 
>> which is a possibility in a lot of functions. Have other people 
>> encountered this as well, and if yes, how are you guys dealing with it? 
>> Thanks in advance... 
>>
>> Kind regards, 
>>
>> Dimitris 
>>
>> [1]: (= [:a Double/NaN] [:a Double/NaN]) => false 
>>
>>
>>
>> -- 
> 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.


Re: clojure.spec predicate generator question

2016-11-07 Thread Alex Miller

On Sunday, November 6, 2016 at 5:01:23 AM UTC-6, Jim foo.bar wrote:
>
> Hi all,
>
> Without having looked at the test.check internals, I'm trying to figure 
> out roughly what kind of generator function, the following spec will give:
>
> (s/def ::predicate  (s/fspec :args (s/cat :x any?)
>  :ret boolean?))
>
>
fdef or fspec will generate a function that checks that assert the incoming 
args match the :args spec and then return a value generated by the :ret 
spec.

 

> So, I'm trying to sort of reverse engineer it on the repl:
>
> (def p (second (first (s/exercise ::predicate 1
> => #'specs.encore/p
> p
> =>
> #object[clojure.spec$fspec_impl$reify__14282$fn__14285
> 0x5cb07a8d
> "clojure.spec$fspec_impl$reify__14282$fn__14285@5cb07a8d"]
> (p 1)
> => false
> (p [])
> => false
> *(p :a)*
> *=> true *
> (p :b)
> => false
> *(p :a)*
> *=> true*
> *(p :a)*
> *=> false* 
>
> Ok, so the predicate returned does not always return the same boolean 
> value (so not constructed via `constantly`). But it also returns a 
> different boolean, given the same argument (so not a real predicate in the 
> sense that it looks at the argument and then decides)! Only one option 
> remains, as far as I can see...`p` seems to return true or false randomly. 
> Can anyone confirm this?
>

This is consistent with my description above.
 

> If my understanding is correct, how would one write the :fn spec of a 
> function like `clojure.core/remove`? Wouldn't it make sense to try to 
> verify that the :ret collection does NOT contain any elements satisfying 
> the predicate used? Similarly for `clojure.core/filter`. A reasonable :fn 
> spec for it should try to confirm that ALL elements in :ret  satisfy that 
> predicate used, right? But if the predicate generated returns true/false 
> randomly, one cannot reliably use it under the :fn spec. Unless, I'm 
> missing something of course...Thanks in advance :)
>

You can write a :fn spec that does all of those things, however the 
generated function spec will not verify those. It would maybe be a 
reasonable enhancement to verify that the :fn spec is satisfied wrt the 
passed args and the generated :ret value (by adding a such-that generator 
based that enhances the ret generator. This is likely to make function 
generators work harder / fail more easily, but you would have greater 
guarantees when it did pass. Seems worthy of an enhancement ticket.

You can use stest/instrument to supply alternative specs and/or generator 
overrides for a function and that would be my recommended strategy right 
now.
 

> Kind regards,
>
> Dimitris
>
>
>
>
>
>

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


Re: clojure.spec gen-testing VS NaN

2016-11-07 Thread dimitris

Hi Alex,

Oh yeah I've seen `s/double-in` but as you point out that doesn't help 
me if I want to :ret spec a function with similar semantics as remove (a 
fn that transforms a seq given a predicate), which I find a very common 
indeed.  I'm only starting playing with clojure.spec (in fact i've only 
spec'ed 2 fns so far) and I've not yet had to spec specifically a 
double-precision number. I have had however the need to spec :any? as 
::anything-but-NaN, in both my first 2 specs, so according to my 
experience this is by no means a rare issue. In fact, looking at 
clojure.core, most fns operate on seqs, and a good proportion of them 
processes/transforms a coll according to a predicate/fn. This has 
nothing to do with doubles or in fact numbers. We can only spec the 
contents of the collection as `any?` right? anything more specific, and 
the gen-surface area is reduced. So yeah it's great that we have 
`s/double-in`, but ideally I'd also like a reliable way to say that the 
output coll from a fn is equal to the input coll, while having specified 
the contents of that coll with `any?`, and without having to jump 
through hoops in the :ret spec. My workaround is actually working nicely 
for me, and i can certainly live without NaNs in the tests, but it still 
feels a bit hacky.


Thanks,

Dimitris


On 07/11/16 18:14, Alex Miller wrote:
Please also take a look at s/double-in, which allows you to exclude 
NaN (and Infinity/-Infinity) as valid values.


(I realize this does not address the any? question, but that seems 
like a rarer issue to me than cases where I'm explicitly spec'ing a 
double but don't want to allow NaN.)


On Monday, November 7, 2016 at 11:37:08 AM UTC-6, Jim foo.bar wrote:

Hi all,

clojure.spec helped me realise that NaNs totally break [1]
equality (per
`clojure.core/=`). Even though in real production code this might
not be
an issue due to how infrequently one deals with NaNs, but during
gen-testing I've found them extremely annoying, and I've essentially
worked around this by spec-ing things I'd normally specify via
`any?`,
via `(s/and any? (complement double-NaN?))` instead. I have to do
this
for any spec, where in the :ret spec i need to be able to confirm
that
the input coll is equal to the output coll (e.g.
`clojure.core/remove`
returns the same coll it was passed in when nothing has been
removed),
which is a possibility in a lot of functions. Have other people
encountered this as well, and if yes, how are you guys dealing
with it?
Thanks in advance...

Kind regards,

Dimitris

[1]: (= [:a Double/NaN] [:a Double/NaN]) => false



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


Re: clojure.spec gen-testing VS NaN

2016-11-07 Thread Alex Miller
Please also take a look at s/double-in, which allows you to exclude NaN 
(and Infinity/-Infinity) as valid values.

(I realize this does not address the any? question, but that seems like a 
rarer issue to me than cases where I'm explicitly spec'ing a double but 
don't want to allow NaN.)

On Monday, November 7, 2016 at 11:37:08 AM UTC-6, Jim foo.bar wrote:
>
> Hi all, 
>
> clojure.spec helped me realise that NaNs totally break [1] equality (per 
> `clojure.core/=`). Even though in real production code this might not be 
> an issue due to how infrequently one deals with NaNs, but during 
> gen-testing I've found them extremely annoying, and I've essentially 
> worked around this by spec-ing things I'd normally specify via `any?`, 
> via `(s/and any? (complement double-NaN?))` instead. I have to do this 
> for any spec, where in the :ret spec i need to be able to confirm that 
> the input coll is equal to the output coll (e.g. `clojure.core/remove` 
> returns the same coll it was passed in when nothing has been removed), 
> which is a possibility in a lot of functions. Have other people 
> encountered this as well, and if yes, how are you guys dealing with it? 
> Thanks in advance... 
>
> Kind regards, 
>
> Dimitris 
>
> [1]: (= [:a Double/NaN] [:a Double/NaN]) => false 
>
>
>
>

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


Re: clojure.spec - relationship between :args

2016-11-07 Thread dimitris

Hi Michal,

Oh yeah,  I've actually improved the spec I shared over the weekend, in 
a similar direction you're hinting. Basically, i've split the :found & 
:not-found cases, and using `gen/one-of`. Many thanks :)


regards,

Dimitris




On 07/11/16 11:41, Michał Marczyk wrote:
Only one quick bit of feedback – it's preferable to use test.check 
facilities instead of (rand) because they're "repeatable": the seed 
emitted in test.check output can be used to rerun the test with the 
same test.check PRNG state (see the docstring on 
clojure.test.check/quick-check, specifically the :seed option), but if 
you call out to other PRNGs, you defeat that mechanism and you'll 
still get different results on different runs. So here you might want 
to say (gen/elements [:head :tails]).


Cheers,
Michał


On 5 November 2016 at 11:59, dimitris > wrote:


Hi Alex,

I think I've figured it out. Here is the complete solution I've
come up with in case you feel like providing feedback:

(defn- extract-sensible-k-gen
   "Gen override for `::extract-args`." []
   (gen/bind (spc/gen ::persistent-coll)
 #(let [r (rand)
heads? (>= r0.5)];; flip a coin (gen/tuple (gen/elements (cond 
(empty? %) (repeat 2 :NOT-FOUND);; nothing can be possibly found in an empty coll 
(map? %) (if heads?
 (keys %);; keys that will be found (repeat 2 
:NOT-FOUND));; keys that will not be found (set? %) (if heads?
 %;; elements (repeat 2 :NOT-FOUND))
  (sequential? %) (let [c (count %)]
(if heads?;; index overrides (if (> r0.75)
(range c);;valid indices (concat (range 
-1 (dec (- c))-1);; invalid (negative) indices (range c (+ c10
  (if (> r0.25);; predicate overrides 
(repeat 2 (constantly true))
(repeat 2 (constantly false)
  ))
  (gen/return %)))
 ))


;==
(spc/def ::persistent-coll (spc/or :map (spc/map-of any? any?)
 :vector (spc/coll-of any?:kind vector?)
 :set (spc/coll-of any?:kind set?)
 :list (spc/coll-of any?:kind list?)))

(spc/def ::predicate (spc/fspec :args (spc/cat :x any?) :ret boolean?))

(spc/def ::extract-args (spc/cat :k (spc/or :predicate ::predicate 
:key-or-index any?)
:coll ::persistent-coll))

(spc/fdef enc/extract

   :args ::extract-args :ret (spc/tuple any? coll?) :fn (spc/or
:some-found #(let [[e c] (:ret %)
[coll-type arg-coll] (-> %:args :coll)]
   (and (some? e)
(> (count arg-coll)
   (count c))
#_(do (println "SOME-FOUND - cret=" c "argc=" 
arg-coll \newline
(-> % :args :k second)) true) )) :nil-found #(let [[e c] (:ret %)
   [coll-type arg-coll] (-> %:args :coll)]
  (and (nil? e)
   (> (count arg-coll)
  (count c))
   #_(do (println "NIL-FOUND - cret=" c "argc=" 
arg-coll \newline (->
% :args :k second)) true) )) :not-found #(let [[e c] (:ret %)
   [coll-type arg-coll] (-> %:args :coll)]
  (and (nil? e)
   (= arg-coll c)
   #_(do (println "NOT-FOUND - cret=" c "argc=" 
arg-coll \newline (->
% :args :k second)) true) )))
   )

 and i call it like so:

(-> (test/check `treajure.encore/extract {:gen {::extract-args 
extract-sensible-k-gen}})
 test/summarize-results

I must say, i was surprised to see that my humble 8G-ram laptop
can barely deal with the default number of generative tests
(1000), but at least it works :).

Many thanks again, for redirecting me to Stu's video - it all made
much more sense after digesting that.

Regards,

Dimitris

On 04/11/16 00:14, dimitris wrote:


HI Alex,

Many thanks for your response, it was very helpful. I see your
point about customizing the generator, and in fact the video in
the link does something sort of similar to what I am trying to.
So yeah I'll figure it out tomorrow :). Thanks again!

Dimitris

On 03/11/16 18:53, Alex Miller wrote:

On Thursday, November 3, 2016 at 1:12:39 PM UTC-5, Jim foo.bar
wrote:

Hi everyone,

I'm starting to get familiar with clojure.spec, and in my
very first spec I needed to specify relationship between the
args themselves (similar to how :fn specs allow for
specifying some relationship between :args & :ret). Is that
  

Re: clojure.spec - relationship between :args

2016-11-07 Thread Michał Marczyk
Only one quick bit of feedback – it's preferable to use test.check
facilities instead of (rand) because they're "repeatable": the seed emitted
in test.check output can be used to rerun the test with the same test.check
PRNG state (see the docstring on clojure.test.check/quick-check,
specifically the :seed option), but if you call out to other PRNGs, you
defeat that mechanism and you'll still get different results on different
runs. So here you might want to say (gen/elements [:head :tails]).

Cheers,
Michał


On 5 November 2016 at 11:59, dimitris  wrote:

> Hi Alex,
>
> I think I've figured it out. Here is the complete solution I've come up
> with in case you feel like providing feedback:
>
> (defn- extract-sensible-k-gen
>   "Gen override for `::extract-args`."  []
>   (gen/bind(spc/gen ::persistent-coll)
> #(let [r (rand)
>heads? (>= r 0.5)] ;; flip a coin   (gen/tuple 
> (gen/elements   (cond (empty? %) (repeat 2 :NOT-FOUND) ;; 
> nothing can be possibly found in an empty coll (map? %) (if heads?
> (keys %) ;; keys that will be found   
>  (repeat 2 :NOT-FOUND)) ;; keys that will not be found (set? 
> %) (if heads?
> % ;; elements(repeat 2 
> :NOT-FOUND))
>  (sequential? %) (let [c (count %)]
>(if heads? ;; index overrides  
>(if (> r 0.75)
>(range c) ;;valid indices  
>  (concat (range -1 (dec (- c)) -1) ;; invalid (negative) 
> indices   (range c (+ c 10
>  (if (> r 0.25) ;; predicate overrides
>(repeat 2 (constantly true))
>(repeat 2 (constantly false)
>  ))
>  (gen/return %)))
> ))
>
> ;==(spc/def
>  ::persistent-coll  (spc/or:map (spc/map-of any? any?)
> :vector (spc/coll-of any? :kind vector?)
> :set (spc/coll-of any? :kind set?)
> :list (spc/coll-of any? :kind list?)))
>
> (spc/def ::predicate  (spc/fspec :args (spc/cat :x any?)
>  :ret boolean?))
>
> (spc/def ::extract-args  (spc/cat :k (spc/or:predicate 
> ::predicate:key-or-index any?)
>:coll ::persistent-coll))
>
> (spc/fdef enc/extract
>
>   :args ::extract-args  :ret (spc/tuple any? coll?)
>
>   :fn (spc/or:some-found #(let [[e c] (:ret %)
>[coll-type arg-coll] (-> % :args :coll)]
>   (and (some? e)
>(> (count arg-coll)
>   (count c))
>#_(do (println "SOME-FOUND - cret=" c "argc=" 
> arg-coll \newline (-> % :args :k second))   true) 
>   ))
> :nil-found #(let [[e c] (:ret %)
>   [coll-type arg-coll] (-> % :args :coll)]
>  (and (nil? e)
>   (> (count arg-coll)
>  (count c))
>   #_(do (println "NIL-FOUND - cret=" c "argc=" 
> arg-coll \newline (-> % :args :k second))  true)  
> ))
> :not-found #(let [[e c] (:ret %)
>   [coll-type arg-coll] (-> % :args :coll)]
>  (and (nil? e)
>   (= arg-coll c)
>   #_(do (println "NOT-FOUND - cret=" c "argc=" 
> arg-coll \newline (-> % :args :k second))  true)  
> )))
>   )
>
>  and i call it like so:
>
> (-> (test/check `treajure.encore/extract {:gen {::extract-args 
> extract-sensible-k-gen}})
> test/summarize-results
>
> I must say, i was surprised to see that my humble 8G-ram laptop can barely
> deal with the default number of generative tests (1000), but at least it
> works :).
>
> Many thanks again, for redirecting me to Stu's video - it all made much
> more sense after digesting that.
>
> Regards,
>
> Dimitris
>
> On 04/11/16 00:14, dimitris wrote:
>
> HI Alex,
>
> Many thanks for your response, it was very helpful. I see your point about
> customizing the generator, and in fact the video in the link does something
> sort of similar to what I am trying to. So yeah I'll figure it out tomorrow
> :). Thanks again!
>
> Dimitris
>
> On 03/11/16 18:53, Alex Miller wrote:
>
>
>
> On Thursday, November 3, 2016 at 1:12:39 PM UTC-5, Jim foo.bar wrote:
>>
>> Hi everyone,
>>
>> I'm starting to get familiar with clojure.spec, and in my very first spec
>> I needed to specify relationship between the args themselves (similar to
>> how :fn specs allow for 

Re: clojure.spec - relationship between :args

2016-11-05 Thread dimitris

Hi Alex,

I think I've figured it out. Here is the complete solution I've come up 
with in case you feel like providing feedback:


(defn- extract-sensible-k-gen
  "Gen override for `::extract-args`." []
  (gen/bind (spc/gen ::persistent-coll)
#(let [r (rand)
   heads? ( >= r0.5)];; flip a coin (gen/tuple (gen/elements (cond 
(empty? %) (repeat 2 :NOT-FOUND);; nothing can be possibly found in an empty coll 
(map? %) (if heads?
(keys %);; keys that will be found (repeat 2 
:NOT-FOUND));; keys that will not be found (set? %) (if heads?
%;; elements (repeat 2 :NOT-FOUND))
 (sequential? %) (let [c (count %)]
   (if heads?;; index overrides (if ( > r0.75)
   (range c);;valid indices (concat (range -1 
(dec (- c))-1);; invalid (negative) indices (range c (+ c10
 (if ( > r0.25);; predicate overrides (repeat 2 
(constantly true))
   (repeat 2 (constantly false)
 ))
 (gen/return %)))
))


;== 
(spc/def ::persistent-coll (spc/or :map (spc/map-of any? any?)
:vector (spc/coll-of any?:kind vector?)
:set (spc/coll-of any?:kind set?)
:list (spc/coll-of any?:kind list?)))

(spc/def ::predicate (spc/fspec :args (spc/cat :x any?)
 :ret boolean?))

(spc/def ::extract-args (spc/cat :k (spc/or :predicate ::predicate 
:key-or-index any?)
   :coll ::persistent-coll))

(spc/fdef enc/extract

  :args ::extract-args :ret (spc/tuple any? coll?)

  :fn (spc/or :some-found #(let [[e c] (:ret %)
   [coll-type arg-coll] (-> %:args :coll)]
  (and (some? e)
   ( > (count arg-coll)
  (count c))
   #_(do (println "SOME-FOUND - cret=" c "argc=" arg-coll \newline (-> % 
:args :k second)) true) ))

:nil-found #(let [[e c] (:ret %)
  [coll-type arg-coll] (-> %:args :coll)]
 (and (nil? e)
  ( > (count arg-coll)
 (count c))
  #_(do (println "NIL-FOUND - cret=" c "argc=" arg-coll \newline (-> % 
:args :k second)) true) ))

:not-found #(let [[e c] (:ret %)
  [coll-type arg-coll] (-> %:args :coll)]
 (and (nil? e)
  (= arg-coll c)
  #_(do (println "NOT-FOUND - cret=" c "argc=" arg-coll \newline (-> % 
:args :k second)) true) )))

  )

 and i call it like so:

(-> (test/check `treajure.encore/extract {:gen {::extract-args 
extract-sensible-k-gen}})
test/summarize-results

I must say, i was surprised to see that my humble 8G-ram laptop can 
barely deal with the default number of generative tests (1000), but at 
least it works :).


Many thanks again, for redirecting me to Stu's video - it all made much 
more sense after digesting that.


Regards,

Dimitris


On 04/11/16 00:14, dimitris wrote:


HI Alex,

Many thanks for your response, it was very helpful. I see your point 
about customizing the generator, and in fact the video in the link 
does something sort of similar to what I am trying to. So yeah I'll 
figure it out tomorrow :). Thanks again!


Dimitris


On 03/11/16 18:53, Alex Miller wrote:



On Thursday, November 3, 2016 at 1:12:39 PM UTC-5, Jim foo.bar wrote:

Hi everyone,

I'm starting to get familiar with clojure.spec, and in my very
first spec I needed to specify relationship between the args
themselves (similar to how :fn specs allow for specifying some
relationship between :args & :ret). Is that at all possible?


:fn is the best way to do this (specifying a relationship either 
between args or between an arg and ret)


Here is my use-case for the sake of argument:

(defn extract
   "Analogous to `clojure.core/get`, but returns a vector of
`[item-at-k, coll-without-k]`. For Sequential things  can be
an integer (the index), or a predicate. In case of a predicate,
the first item that satisfies it will be extracted." [k coll]
   ...)

The implementation is quite simple but irrelevant for my question
and therefore omitted. Here are some sample invocations:

(extract :a {:a 1 :b 2}) => [1 {:b 2}]

(extract :a #{:a :b}) => [:a #{:b}]

(extract 1 [:a :b :c]) => [:b [:a :c]]

(extract (partial = b) [:a :b :c]) => [:b [:a :c]] ;; same as above

(extract 3 [:a :b :c]) => [nil [:a :b :c]] ;; nothing found

And here is my attempt at spec-ing this:

(spc/def ::predicate (spc/fspec :args (spc/cat :x any?)
  :ret boolean?))

(spc/fdef extract

   :args (spc/cat :value (spc/alt :index nat-int?
   ;:key any? FIXME::predicate ::predicate )
  

Re: clojure.spec - relationship between :args

2016-11-03 Thread dimitris

HI Alex,

Many thanks for your response, it was very helpful. I see your point 
about customizing the generator, and in fact the video in the link does 
something sort of similar to what I am trying to. So yeah I'll figure it 
out tomorrow :). Thanks again!


Dimitris


On 03/11/16 18:53, Alex Miller wrote:



On Thursday, November 3, 2016 at 1:12:39 PM UTC-5, Jim foo.bar wrote:

Hi everyone,

I'm starting to get familiar with clojure.spec, and in my very
first spec I needed to specify relationship between the args
themselves (similar to how :fn specs allow for specifying some
relationship between :args & :ret). Is that at all possible?


:fn is the best way to do this (specifying a relationship either 
between args or between an arg and ret)


Here is my use-case for the sake of argument:

(defn extract
   "Analogous to `clojure.core/get`, but returns a vector of
`[item-at-k, coll-without-k]`. For Sequential things  can be an
integer (the index), or a predicate. In case of a predicate, the
first item that satisfies it will be extracted." [k coll]
   ...)

The implementation is quite simple but irrelevant for my question
and therefore omitted. Here are some sample invocations:

(extract :a {:a 1 :b 2}) => [1 {:b 2}]

(extract :a #{:a :b}) => [:a #{:b}]

(extract 1 [:a :b :c]) => [:b [:a :c]]

(extract (partial = b) [:a :b :c]) => [:b [:a :c]] ;; same as above

(extract 3 [:a :b :c]) => [nil [:a :b :c]] ;; nothing found

And here is my attempt at spec-ing this:

(spc/def ::predicate (spc/fspec :args (spc/cat :x any?)
  :ret boolean?))

(spc/fdef extract

   :args (spc/cat :value (spc/alt :index nat-int?
   ;:key any? FIXME::predicate ::predicate )
  :coll coll?)

   :ret (spc/tuple any? coll?)

   :fn (spc/or :some-found #(let [[e c] (:ret %)
arg-coll (-> %:args :coll)]
   (and (some? e)
(> (count arg-coll)
   (count c
 :nil-found #(let [[e c] (:ret %)
   arg-coll (-> %:args :coll)]
  (and (nil? e)
   (> (count arg-coll)
  (count c
 :not-found #(let [[e c] (:ret %)
   arg-coll (-> %:args :coll)]
  (and (nil? e)
   (= arg-coll c
   )


So, as you can probably see, there are 2 problems with this:

1) Even though, I've verified that ::predicate gens correct
predicates (via `s/exercise`), when i try to gen-test it, it finds
predicates which are causing `extract` to return something like
`[x (x)]` (where x can be anything). So, it seems that there exist
predicates that cause `extract` to find the item, but not remove
it from coll. This is something that i can't reproduce manually!


Is the info on the failing example in this case not sufficient enough 
to determine the failing case? I think it's worth at least considering 
the possibility that your code has a bug. :) Maybe the info is not 
sufficient, but I can judge without seeing the output and the actual code.


2) You may have noticed a `FIXME` in the :args spec. I would like
to enumerate the 3 possible/logical types of `:value (nat-int? or
::predicate for sequentials, but `any?` for maps/sets).


I don't think it's a good idea to separate the nat-int? and any? cases 
- I would just use any? in this case. The key here (and really 
everywhere you're writing an arg spec) is to try to state the truth as 
much as you can. The truth here is that anything can be a key (even 
though there is an identifiable case where the keys happen to be ints).


If i uncomment what i currently have i can see that gen-testing
will eventually mix something that is not an index nor a
::predicate (e.g. a string) with something sequential, which is
not supposed to happen.

So basically I'm stuck with this. If i comment out the `:predicate
::predicate` entry, then it passes gen-testing, but actually it
has only really tested 1/3 of the possible intended usages. :( Ok,
you might say that integers are perfectly valid keys in maps or
elements in sets, and so perhaps one could claim that 2/3 have
been tested. Is there any way of fully spec-ing this fn, or should
i just stick to a good doc-string and manually crafted test-cases?


You should definitely spec it! But this is a case where a custom 
generator is called for - in particular one that takes into account a 
better model for the inputs to the function. Stu Halloway did a whole 
screencast on this at
https://www.youtube.com/watch?v=WoFkhE92fqc and I would recommend 
fully understanding that approach. The gist is that instead of 
generating the 

Re: clojure.spec - relationship between :args

2016-11-03 Thread Alex Miller


On Thursday, November 3, 2016 at 1:12:39 PM UTC-5, Jim foo.bar wrote:
>
> Hi everyone,
>
> I'm starting to get familiar with clojure.spec, and in my very first spec 
> I needed to specify relationship between the args themselves (similar to 
> how :fn specs allow for specifying some relationship between :args & :ret). 
> Is that at all possible? 
>

:fn is the best way to do this (specifying a relationship either between 
args or between an arg and ret)
 

> Here is my use-case for the sake of argument:
>
> (defn extract
>   "Analogous to `clojure.core/get`, but returns a vector of `[item-at-k, 
> coll-without-k]`.   For Sequential things  can be an integer (the index), 
> or a predicate.   In case of a predicate, the first item that satisfies it 
> will be extracted."  [k coll]
>   ...)
>
> The implementation is quite simple but irrelevant for my question and 
> therefore omitted. Here are some sample invocations:
>
> (extract :a {:a 1 :b 2}) => [1 {:b 2}]
>
> (extract :a #{:a :b}) => [:a #{:b}]
>
> (extract 1 [:a :b :c]) => [:b [:a :c]]
>
> (extract (partial = b) [:a :b :c]) => [:b [:a :c]] ;; same as above
>
> (extract 3 [:a :b :c]) => [nil [:a :b :c]] ;; nothing found
>
> And here is my attempt at spec-ing this:
>
> (spc/def ::predicate  (spc/fspec :args (spc/cat :x any?)
>  :ret boolean?))
>
> (spc/fdef extract
>
>   :args (spc/cat :value (spc/alt  :index nat-int?
>   ;:key any?  FIXME:  
> :predicate ::predicate  )
>  :coll coll?)
>
>   :ret (spc/tuple any? coll?)
>
>   :fn (spc/or:some-found #(let [[e c] (:ret %)
>arg-coll (-> % :args :coll)]
>   (and (some? e)
>(> (count arg-coll)
>   (count c
> :nil-found #(let [[e c] (:ret %)
>   arg-coll (-> % :args :coll)]
>  (and (nil? e)
>   (> (count arg-coll)
>  (count c
> :not-found #(let [[e c] (:ret %)
>   arg-coll (-> % :args :coll)]
>  (and (nil? e)
>   (= arg-coll c
>   )
>
>
> So, as you can probably see, there are 2 problems with this:
>
> 1) Even though, I've verified that ::predicate gens correct predicates 
> (via `s/exercise`), when i try to gen-test it, it finds predicates which 
> are causing `extract` to return something like `[x (x)]` (where x can be 
> anything). So, it seems that there exist predicates that cause `extract` to 
> find the item, but not remove it from coll. This is something that i can't 
> reproduce manually!
>

Is the info on the failing example in this case not sufficient enough to 
determine the failing case? I think it's worth at least considering the 
possibility that your code has a bug. :) Maybe the info is not sufficient, 
but I can judge without seeing the output and the actual code.
 

> 2) You may have noticed a `FIXME` in the :args spec. I would like to 
> enumerate the 3 possible/logical types of `:value (nat-int? or ::predicate 
> for sequentials, but `any?` for maps/sets). 
>

I don't think it's a good idea to separate the nat-int? and any? cases - I 
would just use any? in this case. The key here (and really everywhere 
you're writing an arg spec) is to try to state the truth as much as you 
can. The truth here is that anything can be a key (even though there is an 
identifiable case where the keys happen to be ints).
 

> If i uncomment what i currently have i can see that gen-testing will 
> eventually mix something that is not an index nor a ::predicate (e.g. a 
> string) with something sequential, which is not supposed to happen.
>
> So basically I'm stuck with this. If i comment out the `:predicate 
> ::predicate` entry, then it passes gen-testing, but actually it has only 
> really tested 1/3 of the possible intended usages. :( Ok, you might say 
> that integers are perfectly valid keys in maps or elements in sets, and so 
> perhaps one could claim that 2/3 have been tested. Is there any way of 
> fully spec-ing this fn, or should i just stick to a good doc-string and 
> manually crafted test-cases? 
>

You should definitely spec it! But this is a case where a custom generator 
is called for - in particular one that takes into account a better model 
for the inputs to the function. Stu Halloway did a whole screencast on this 
at 
https://www.youtube.com/watch?v=WoFkhE92fqc and I would recommend fully 
understanding that approach. The gist is that instead of generating the key 
to find and the collection independently, you want to instead create a 
model of multiple cases. When you're trying to model the case where a key 
is found, don't generate it randomly - instead generate the coll, and use 
one of its keys.

Hope that helped.
 

> Thanks in advance - any feedback is greatly 

Re: clojure.spec: Relationships Between Specs

2016-10-19 Thread Mark Bastian
Very cool. Thanks!

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


Re: clojure.spec: Relationships Between Specs

2016-10-19 Thread Alex Miller
Sorry, should have been :req, not ::req in there. :)

It generates too:

user=> (gen/sample (s/gen ::xrange))
(#:user{:x0 0, :x1 1} #:user{:x0 1, :x1 5} #:user{:x0 0, :x1 1} #:user{:x0 
0, :x1 1} #:user{:x0 2, :x1 9} #:user{:x0 0, :x1 13} #:user{:x0 0, :x1 6} 
#:user{:x0 1, :x1 62} #:user{:x0 2, :x1 97} #:user{:x0 1, :x1 90})


On Wednesday, October 19, 2016 at 1:49:03 PM UTC-5, Alex Miller wrote:
>
> s/and will flow the conformed result to the next predicate so something 
> like this should work:
>
> (s/def ::xrange 
>   (s/and (s/keys ::req [::x0 ::x1]) 
>  (fn [{:keys [::x0 ::x1]}] (< x0 x1
>
> On Wednesday, October 19, 2016 at 12:27:04 PM UTC-5, Mark Bastian wrote:
>>
>> Is it possible to specify relationships between spec values. For example:
>>
>> (s/def ::x0 (int-in 0 100))
>> (s/def ::x1 (int-in 0 100))
>>
>> ;I now want to say something along the lines of (note that the :where is 
>> totally made up - just conveying the intent):
>> (s/def ::xrange (s/keys ::req [::x0 ::x1 :where  (< ::x0 ::x1)]))
>>
>> How might I do this?
>>
>> Thanks in advance!
>> Mark
>>
>

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


Re: clojure.spec: Relationships Between Specs

2016-10-19 Thread Alex Miller
s/and will flow the conformed result to the next predicate so something 
like this should work:

(s/def ::xrange 
  (s/and (s/keys ::req [::x0 ::x1]) 
 (fn [{:keys [::x0 ::x1]}] (< x0 x1

On Wednesday, October 19, 2016 at 12:27:04 PM UTC-5, Mark Bastian wrote:
>
> Is it possible to specify relationships between spec values. For example:
>
> (s/def ::x0 (int-in 0 100))
> (s/def ::x1 (int-in 0 100))
>
> ;I now want to say something along the lines of (note that the :where is 
> totally made up - just conveying the intent):
> (s/def ::xrange (s/keys ::req [::x0 ::x1 :where  (< ::x0 ::x1)]))
>
> How might I do this?
>
> Thanks in advance!
> Mark
>

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


Re: clojure.spec, conform and returned value

2016-10-11 Thread Alex Miller


On Tuesday, October 11, 2016 at 1:30:18 PM UTC-5, plamen.use...@gmail.com 
wrote:
>
> Hello,
>
> I have a problem which is probably not in the spirit of clojure.spec as 
> being a library for "only" checking/generating valid values, but of 
> substantial practical value for my use case:
>
> Let say I have a function for checking if a double precision number is 
> parsable from a string (where possible performance penalties because of 
> communicating non-parsable strings through try/catch in the implementation 
> is not part of my question):
>
>
> (defn str-parsable-double? [s]
>   "Note the IMPLIED transformation from string to a double"
>   (try
> (Double/valueOf s)
> (catch NumberFormatException e
>   false)))
>
>
>
It's not detrimental here (other than this fn won't have the intended 
docstring), but this code has the docstring in the wrong place - it goes 
before the arglist, not after. 
 

> and have a spec using this function:
>
> (s/def ::str->double str-parsable-double?)
>
>
> We could actually chain checks for a single value as in:
>
> (s/def ::str->double (s/and string? str-parsable-double?))
>
>
This is a good practice. In general most specs will not generate 
automatically unless you start from a type-based predicate so this 
particular part I think is very much in line with good practices.
 

> and we could check for the conformity of a value as per:
>
> (s/conform ::str->double "3.14")
> => "3.14"
> and 
> (s/conform ::str->double "Pizza")
> => :clojure.spec/invalid
>
> Until now everything is ok, now my the questions:
>
> In my real world example I need a chain of a combination of checks and 
> transformations in the following way:
> ::check1 ::check2 ::check-and-transform3 ::check-4-on-transformed-value 
> ::check-5-on-transformed value
> or something like
> (s/def ::transforming-check (s/and string? ::str->double ::bigger-than-zero? 
> ::smaller-than-pi ... etc ...))
>
> As the result of 
> (s/conform ::str->double "3.14") is the input value as a string instead of 
> the result, 
>
>
I would need implement ::bigger-than-zero? and the rest of the checks as 
operating on strings, which would mean that I need in each check to transform 
the string into a double, which in my case is for performance reasons bad.
>
> On the other side I would be able to do the checks in a 2 step fashion, which 
> goes against my understanding of the aim of clojure.check to be able to 
> create through composition a single set of validations for a single value.
> This also doesn't solve fully the problem with the multiple parsing of the 
> first data type before the transformation: a parsing happens in the 
> ::str->double step as well in the then explicit transformation step before 
> the final checks based then on the actual double.
>
>
You can use s/conformer for this, although I will share the caution that 
use of s/conformer in your registered specs means that you are obscuring 
(and throwing away info) from the input value for your spec consumers. This 
is not inherently bad, but it is a tradeoff that should be considered when 
mixing validation and conversion. You could keep the conversion out of the 
spec and do that via a transformation or via a non-registered spec too. I 
can't say which of these is "right" for you, but you should at least think 
through these things ahead of time. A generally good practice is to also 
supply an unformer function with your conformer (here, probably just str 
would work) - this would allow you to run the spec backwards with s/unform 
and retrieve the original value.



> So - is there a way to compose checks in a single one, where some of them 
> change the underlying type of the value for subsequent validations (I may 
> miss something in the Clojure documentation, and pointers to it would be very 
> welcome)?
>
> If not - why s/conform returns the input value instead of the result value? 
> As being on the caller site of s/conform I know what I passed and I know what 
> s/conform would give me in the negative outcome of the validation.
> If s/conform while iterating/recursing through the actual spec would apply 
> the checks on returned values of previous checks instead always on the input 
> - the problem would be solved, without negatives for the calling sites (as 
> because of the previous sentence).
> This could be solved for example (not sure if I see every detail yet, but at 
> least as a pointer) in that in the clojure.spec code
>
> Spec
> (conform* [_ x] (let [ret (pred x)]
>   (if cpred?
> ret
> (if ret x ::invalid
> the value of cpred? could be passed from the calling site (or if don't miss 
> something be even per default true).
>
> In any case, I would be thankfull for any suggestions solving both proplems: 
> how to express such checks in a good way and how to avoid reparsing values 
> again and again (where the current example is for just strings to doubles, 
> but the actual 

Re: clojure.spec, conform and returned value

2016-10-11 Thread plamen . usenet
Amazing! 

Lot of thanks Josh! This solves everything. It is even written in the API 
doc, but I missed the important piece of "(possibly converted) value"...

With best regards
Plamen

On Tuesday, October 11, 2016 at 8:49:16 PM UTC+2, Josh Tilles wrote:
>
> I think you’re looking for conformer 
> ;
>  
> the spec it produces will pass along the converted value instead of the 
> original input. It could be used like:
> (defn str->double [s]
>   (try
> (Double/valueOf s)
> (catch NumberFormatException _
>   :clojure.spec/invalid)))
>
> (s/def ::transforming-check (s/and string? (s/conformer str->double) ::
> bigger-than-zero?))
>
> I hope that helps with your original problem, but I’ll defer to the more 
> experienced folks here for your questions about the spirit/aim of 
> clojure.spec.
>
> On Tuesday, October 11, 2016 at 2:30:18 PM UTC-4, plamen...@gmail.com 
> wrote:
>>
>> Hello,
>>
>> I have a problem which is probably not in the spirit of clojure.spec as 
>> being a library for "only" checking/generating valid values, but of 
>> substantial practical value for my use case:
>>
>> Let say I have a function for checking if a double precision number is 
>> parsable from a string (where possible performance penalties because of 
>> communicating non-parsable strings through try/catch in the implementation 
>> is not part of my question):
>>
>>
>> (defn str-parsable-double? [s]
>>   "Note the IMPLIED transformation from string to a double"
>>   (try
>> (Double/valueOf s)
>> (catch NumberFormatException e
>>   false)))
>>
>>
>> and have a spec using this function:
>>
>> (s/def ::str->double str-parsable-double?)
>>
>>
>> We could actually chain checks for a single value as in:
>>
>> (s/def ::str->double (s/and string? str-parsable-double?))
>>
>> and we could check for the conformity of a value as per:
>>
>> (s/conform ::str->double "3.14")
>> => "3.14"
>> and 
>> (s/conform ::str->double "Pizza")
>> => :clojure.spec/invalid
>>
>> Until now everything is ok, now my the questions:
>>
>> In my real world example I need a chain of a combination of checks and 
>> transformations in the following way:
>> ::check1 ::check2 ::check-and-transform3 ::check-4-on-transformed-value 
>> ::check-5-on-transformed value
>> or something like
>> (s/def ::transforming-check (s/and string? ::str->double ::bigger-than-zero? 
>> ::smaller-than-pi ... etc ...))
>>
>> As the result of 
>> (s/conform ::str->double "3.14") is the input value as a string instead of 
>> the result, I would need implement ::bigger-than-zero? and the rest of the 
>> checks as operating on strings, which would mean that I need in each check 
>> to transform the string into a double, which in my case is for performance 
>> reasons bad.
>>
>> On the other side I would be able to do the checks in a 2 step fashion, 
>> which goes against my understanding of the aim of clojure.check to be able 
>> to create through composition a single set of validations for a single value.
>> This also doesn't solve fully the problem with the multiple parsing of the 
>> first data type before the transformation: a parsing happens in the 
>> ::str->double step as well in the then explicit transformation step before 
>> the final checks based then on the actual double.
>>
>> So - is there a way to compose checks in a single one, where some of them 
>> change the underlying type of the value for subsequent validations (I may 
>> miss something in the Clojure documentation, and pointers to it would be 
>> very welcome)?
>>
>> If not - why s/conform returns the input value instead of the result value? 
>> As being on the caller site of s/conform I know what I passed and I know 
>> what s/conform would give me in the negative outcome of the validation.
>> If s/conform while iterating/recursing through the actual spec would apply 
>> the checks on returned values of previous checks instead always on the input 
>> - the problem would be solved, without negatives for the calling sites (as 
>> because of the previous sentence).
>> This could be solved for example (not sure if I see every detail yet, but at 
>> least as a pointer) in that in the clojure.spec code
>>
>> Spec
>> (conform* [_ x] (let [ret (pred x)]
>>   (if cpred?
>> ret
>> (if ret x ::invalid
>> the value of cpred? could be passed from the calling site (or if don't miss 
>> something be even per default true).
>>
>> In any case, I would be thankfull for any suggestions solving both proplems: 
>> how to express such checks in a good way and how to avoid reparsing values 
>> again and again (where the current example is for just strings to doubles, 
>> but the actual problem could involve any transformations on the value incl. 
>> type).
>>
>> With best regards
>> Plamen
>>
>>
>>
>>
>>
>>

-- 
You received this message because you are subscribed to 

Re: clojure.spec, conform and returned value

2016-10-11 Thread Josh Tilles
I think you’re looking for conformer 
;
 
the spec it produces will pass along the converted value instead of the 
original input. It could be used like:
(defn str->double [s]
  (try
(Double/valueOf s)
(catch NumberFormatException _
  :clojure.spec/invalid)))

(s/def ::transforming-check (s/and string? (s/conformer str->double) ::
bigger-than-zero?))

I hope that helps with your original problem, but I’ll defer to the more 
experienced folks here for your questions about the spirit/aim of 
clojure.spec.

On Tuesday, October 11, 2016 at 2:30:18 PM UTC-4, plamen...@gmail.com wrote:
>
> Hello,
>
> I have a problem which is probably not in the spirit of clojure.spec as 
> being a library for "only" checking/generating valid values, but of 
> substantial practical value for my use case:
>
> Let say I have a function for checking if a double precision number is 
> parsable from a string (where possible performance penalties because of 
> communicating non-parsable strings through try/catch in the implementation 
> is not part of my question):
>
>
> (defn str-parsable-double? [s]
>   "Note the IMPLIED transformation from string to a double"
>   (try
> (Double/valueOf s)
> (catch NumberFormatException e
>   false)))
>
>
> and have a spec using this function:
>
> (s/def ::str->double str-parsable-double?)
>
>
> We could actually chain checks for a single value as in:
>
> (s/def ::str->double (s/and string? str-parsable-double?))
>
> and we could check for the conformity of a value as per:
>
> (s/conform ::str->double "3.14")
> => "3.14"
> and 
> (s/conform ::str->double "Pizza")
> => :clojure.spec/invalid
>
> Until now everything is ok, now my the questions:
>
> In my real world example I need a chain of a combination of checks and 
> transformations in the following way:
> ::check1 ::check2 ::check-and-transform3 ::check-4-on-transformed-value 
> ::check-5-on-transformed value
> or something like
> (s/def ::transforming-check (s/and string? ::str->double ::bigger-than-zero? 
> ::smaller-than-pi ... etc ...))
>
> As the result of 
> (s/conform ::str->double "3.14") is the input value as a string instead of 
> the result, I would need implement ::bigger-than-zero? and the rest of the 
> checks as operating on strings, which would mean that I need in each check to 
> transform the string into a double, which in my case is for performance 
> reasons bad.
>
> On the other side I would be able to do the checks in a 2 step fashion, which 
> goes against my understanding of the aim of clojure.check to be able to 
> create through composition a single set of validations for a single value.
> This also doesn't solve fully the problem with the multiple parsing of the 
> first data type before the transformation: a parsing happens in the 
> ::str->double step as well in the then explicit transformation step before 
> the final checks based then on the actual double.
>
> So - is there a way to compose checks in a single one, where some of them 
> change the underlying type of the value for subsequent validations (I may 
> miss something in the Clojure documentation, and pointers to it would be very 
> welcome)?
>
> If not - why s/conform returns the input value instead of the result value? 
> As being on the caller site of s/conform I know what I passed and I know what 
> s/conform would give me in the negative outcome of the validation.
> If s/conform while iterating/recursing through the actual spec would apply 
> the checks on returned values of previous checks instead always on the input 
> - the problem would be solved, without negatives for the calling sites (as 
> because of the previous sentence).
> This could be solved for example (not sure if I see every detail yet, but at 
> least as a pointer) in that in the clojure.spec code
>
> Spec
> (conform* [_ x] (let [ret (pred x)]
>   (if cpred?
> ret
> (if ret x ::invalid
> the value of cpred? could be passed from the calling site (or if don't miss 
> something be even per default true).
>
> In any case, I would be thankfull for any suggestions solving both proplems: 
> how to express such checks in a good way and how to avoid reparsing values 
> again and again (where the current example is for just strings to doubles, 
> but the actual problem could involve any transformations on the value incl. 
> type).
>
> With best regards
> Plamen
>
>
>
>
>
>

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

Re: clojure.spec to match string

2016-09-30 Thread Serzh Nechyporchuk
Thanks for all. I will look at your suggestions.
> On Sep 29, 2016, at 20:59, lvh <_...@lvh.io> wrote:
> 
>> 
>> On Sep 29, 2016, at 11:42 AM, Sean Corfield > > wrote:
>> 
>> The test.chuck library from Gary Fredericks has a generator for regex 
>> strings that works pretty well.
> 
> Whenever I get some time (not soon, if my inbox is anything to go by), I’ll 
> add the equivalent part to schpec.
> 
> lvh
> 
>> Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN
>> An Architect's View -- http://corfield.org/
>> 
>> "If you're not annoying somebody, you're not really alive."
>> -- Margaret Atwood
>> 
>> On 9/29/16, 7:20 AM, "Serzh Nechyporchuk" > behalf of nechyporc...@gmail.com> wrote:
>> 
>>   Thank you Alex. That’s true, I can use just predicate to validate string. 
>> But I want a little more from this.
>>   I really want to use generators and conforming. 
>>   I know that strings are seqable, s/cat works with seq. So my question is: 
>> Are there any way to combine this? 
>> 
>>> On Sep 29, 2016, at 15:39, Alex Miller  wrote:
>>> 
>>> You can make a predicate using re-matches - there is an email example in 
>>> http://clojure.org/guides/spec
>> 
>> 
>> 
>> 
>> -- 
>> 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.


Re: clojure.spec to match string

2016-09-29 Thread lvh

> On Sep 29, 2016, at 11:42 AM, Sean Corfield  wrote:
> 
> The test.chuck library from Gary Fredericks has a generator for regex strings 
> that works pretty well.

Whenever I get some time (not soon, if my inbox is anything to go by), I’ll add 
the equivalent part to schpec.

lvh

> Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN
> An Architect's View -- http://corfield.org/
> 
> "If you're not annoying somebody, you're not really alive."
> -- Margaret Atwood
> 
> On 9/29/16, 7:20 AM, "Serzh Nechyporchuk"  of nechyporc...@gmail.com> wrote:
> 
>Thank you Alex. That’s true, I can use just predicate to validate string. 
> But I want a little more from this.
>I really want to use generators and conforming. 
>I know that strings are seqable, s/cat works with seq. So my question is: 
> Are there any way to combine this? 
> 
>> On Sep 29, 2016, at 15:39, Alex Miller  wrote:
>> 
>> You can make a predicate using re-matches - there is an email example in 
>> http://clojure.org/guides/spec
> 
> 
> 
> 
> -- 
> 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.


Re: clojure.spec to match string

2016-09-29 Thread Sean Corfield
The test.chuck library from Gary Fredericks has a generator for regex strings 
that works pretty well.

Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN
An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood

On 9/29/16, 7:20 AM, "Serzh Nechyporchuk"  wrote:

Thank you Alex. That’s true, I can use just predicate to validate string. 
But I want a little more from this.
I really want to use generators and conforming. 
I know that strings are seqable, s/cat works with seq. So my question is: 
Are there any way to combine this? 

> On Sep 29, 2016, at 15:39, Alex Miller  wrote:
> 
> You can make a predicate using re-matches - there is an email example in 
http://clojure.org/guides/spec




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


Re: clojure.spec to match string

2016-09-29 Thread Serzh Nechyporchuk
Thank you Alex. That’s true, I can use just predicate to validate string. But I 
want a little more from this.
I really want to use generators and conforming. 
I know that strings are seqable, s/cat works with seq. So my question is: Are 
there any way to combine this? 

> On Sep 29, 2016, at 15:39, Alex Miller  wrote:
> 
> You can make a predicate using re-matches - there is an email example in 
> http://clojure.org/guides/spec
> 
> -- 
> 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.


Re: clojure.spec question

2016-09-24 Thread Alex Miller
#{{"id" 1 "name" "john"}} is a valid spec for that

On Saturday, September 24, 2016 at 9:46:55 AM UTC-5, Philos Kim wrote:
>
> How can I define the following spec?
>
> {"id" 1 "name" "john"}
>
> 1) The keys of a map must be the string type, not the keyword type.
>
> 2) The values must be fixed. Namely, the value of the key "id" must be 1 
> and the value of the key "name" must be "john"
>
>

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


Re: clojure.spec - suggestion on how to simplify :pre and :post conditions by using specs.

2016-09-16 Thread joakim . tengstrand
I think a natural place of the :post condition shold be after the argument 
brackets (and that should be possible to implement I think):

(defn user-name [user :core/user] :user/name
  (-> user :user/name))


On Friday, September 16, 2016 at 1:34:47 PM UTC+2, joakim.t...@nova.com 
wrote:
>
> (ns spec-test.core
>   (:require [clojure.spec :as s]))
>
> (s/def :user/name string?)
> (s/def :core/user (s/keys :req [:user/name]))
>
> ; A helper method to get better error messages.
> ; Also imagine that clojure.spec has a similar s/check
> ; function that looks similar to this one
> ; (used in our user-name function):
> (defn check [type data]
>   (if (s/valid? type data)
> true
> (throw (AssertionError. (s/explain type data)
>
>
> ; ...how about if we could write our :pre and :post conditions like this:
> (defn user-name [user :core/user]
>   (-> user :user/name)) :user/name
>
> ; ...so that they expands into this:
> (defn user-name [user]
>   {:pre [(s/check :core/user user)]}
>   {:post [(s/check :user/name user)]}
>   (-> user :user/name))
>
>
>
> ; And if you have other :pre or :post conditions,
> ; then extend the existing ones:
> (defn user-name [user :core/user number]
>   {:pre [pos? number]}
>   (-> user :user/name))
>
> ; ...becomes:
> (defn user-name [user number]
>   {:pre [pos? number
>  (s/valid? :core/user user)]}
>   (-> user :user/name))
>
> ; a call to the function
> (user-name {:user/name "Bill"} 3)
>
>
> ; Maybe it will be hard to find a nice syntax that works for the post 
> condition,
> ; but the :pre condition should be doable I think!
>
>

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


Re: clojure.spec - Using :pre conditions (or not)?

2016-09-16 Thread joakim . tengstrand
I agree with you that an IllegalArgumentException is preferable 
to AssertionError.
The reason that I used AssertionError was that I wanted to keep the same 
behaviour as when using s/valid? (it throws an AssertionError).
Maybe only s/assert should throw AssertionError and s/valid? should throw 
something else?

/Joakim

On Friday, September 16, 2016 at 7:52:55 AM UTC+2, Mamun wrote:
>
>
> When function is throwing exception because of argument. I would prefer to 
> throw IllegalArgumentException not AssertionError. 
>
>
> (defn check [type data]
>   (if (sp/valid? type data)
> true
> (throw (IllegalArgumentException. (sp/explain type data)
>
>
> Br,
> Mamun
>
>
> On Friday, September 16, 2016 at 7:20:53 AM UTC+2, joakim.t...@nova.com 
> wrote:
>>
>> I came up with this solution:
>>
>> (ns spec-test.core
>>   (:require [clojure.spec :as s]))
>>
>> (s/def :user/name string?)
>> (s/def :common/user (s/keys :req [:user/name]))
>>
>> ;; with this little helper function...
>> (defn check [type data]
>>   (if (s/valid? type data)
>> true
>> (throw (AssertionError. (s/explain type data)
>>
>> ;; I can use it in my :pre condition
>> (defn aname [user]
>>   {:pre [(check :common/user user)]}
>>   (-> user :user/name))
>>
>> ;; when I call name with an illegal arguement...
>> (aname {:x "Elon"})
>>
>> ;; ...it not fails and returns a better error message:
>> CompilerException java.lang.AssertionError: null, 
>> compiling:(/Users/joakimtengstrand/IdeaProjects/spec-test/src/spec_test/core.clj:19:1)
>> val: {:x "Elon"} fails spec: :common/user predicate: (contains? % :user/name)
>>
>>
>> With this solution I don't need to enable assertions, and the code is 
>> neat and less verbose!
>>
>> /Joakim
>>
>> On Thursday, September 15, 2016 at 3:11:32 PM UTC+2, Shantanu Kumar wrote:
>>>
>>> Hi Joakim,
>>>
>>> You might be interested in Paul Stadig's library 
>>> https://github.com/pjstadig/assertions that leverages Java's `-ea` 
>>> (enable-assertions, which you may want to keep enabled in dev) command-line 
>>> flag. If you have a bunch of things together to assert, you may want to use 
>>> the `when-assert` macro for wholesale optimization: 
>>> https://github.com/pjstadig/assertions/blob/0.2.0/src/pjstadig/assertions.clj#L13
>>>
>>>
>>> Shantanu
>>>
>>> On Thursday, 15 September 2016 16:50:17 UTC+5:30, joakim.t...@nova.com 
>>> wrote:

 Ok, thanks!

 In the Java world, the assertions is also something that need to be 
 turn on explicitly.
 In that sence, they are kind of not mandatory to be executed (or at 
 least signals that to the reader of the code).

 I would be happier if you guys could add another method, that I can use 
 in my :pre conditions, that leverage
 the same amount of details in the error messages, but that is always 
 "turned on".

 In the meanwhile, I will use s/assert ;-)

 BR,
 Joakim Tengstrand


 On Wednesday, 14 September 2016 15:59:09 UTC+2, Alex Miller wrote:
>
> Another option that has been added since the guide was written is 
> s/assert which seems closer to what you're suggesting.
>
> (defn name [user]
>   {:pre [(s/assert :common/user user)]}
>   (-> user :user/name))
>
> ;; need to enable assertion checking - this can also be enabled 
> globally with system property clojure.spec.check-asserts
> (s/check-asserts true)
>
> (name {:user/name "Elon"})
> "Elon"
>
> (name {:x "Elon"})
> ExceptionInfo Spec assertion failed
> val: {:x "Elon"} fails predicate: (contains? % :user/name)
> :clojure.spec/failure  :assertion-failed
>   clojure.core/ex-info (core.clj:4725)
>
> Rather than use it in a precondition, you can also use s/assert 
> directly in the code.
>
> On Wednesday, September 14, 2016 at 7:37:24 AM UTC-5, 
> joakim.t...@nova.com wrote:
>>
>> (ns spec-test.core
>>   (:require [clojure.spec :as s]))
>>
>> (s/def :user/name string?)
>> (s/def :common/user (s/keys :req [:user/name]))
>>
>> ; first version of name (using :pre)
>> (defn name [user]
>>   {:pre [(s/valid? :common/user user)]}
>>   (-> user :user/name))
>>
>> ; This statement works ok and returns "Elon":
>> (name {:user/name "Elon"})
>>
>> ; but this statement...
>> (name {:x "Elon"})
>>
>> ;...will throw:
>> CompilerException java.lang.AssertionError:
>> Assert failed: (s/valid? :common/user user)
>>
>> ; ...but then I don't get as much information
>> ; about the error as if I would have called:
>> (s/explain :common/user {:x "Elon"})
>>
>> ;...which also contains the predicate:
>> val: {:x "Elon"} fails spec: :common/user
>> predicate: (contains? % :user/name)
>>
>> ; (second version of name - more verbose)
>> ; or do I need to wite it like this:
>> (defn name [user]
>>   (let [parsed 

Re: clojure.spec - Using :pre conditions (or not)?

2016-09-15 Thread Mamun

When function is throwing exception because of argument. I would prefer to 
throw IllegalArgumentException not AssertionError. 


(defn check [type data]
  (if (sp/valid? type data)
true
(throw (IllegalArgumentException. (sp/explain type data)


Br,
Mamun


On Friday, September 16, 2016 at 7:20:53 AM UTC+2, joakim.t...@nova.com 
wrote:
>
> I came up with this solution:
>
> (ns spec-test.core
>   (:require [clojure.spec :as s]))
>
> (s/def :user/name string?)
> (s/def :common/user (s/keys :req [:user/name]))
>
> ;; with this little helper function...
> (defn check [type data]
>   (if (s/valid? type data)
> true
> (throw (AssertionError. (s/explain type data)
>
> ;; I can use it in my :pre condition
> (defn aname [user]
>   {:pre [(check :common/user user)]}
>   (-> user :user/name))
>
> ;; when I call name with an illegal arguement...
> (aname {:x "Elon"})
>
> ;; ...it not fails and returns a better error message:
> CompilerException java.lang.AssertionError: null, 
> compiling:(/Users/joakimtengstrand/IdeaProjects/spec-test/src/spec_test/core.clj:19:1)
> val: {:x "Elon"} fails spec: :common/user predicate: (contains? % :user/name)
>
>
> With this solution I don't need to enable assertions, and the code is neat 
> and less verbose!
>
> /Joakim
>
> On Thursday, September 15, 2016 at 3:11:32 PM UTC+2, Shantanu Kumar wrote:
>>
>> Hi Joakim,
>>
>> You might be interested in Paul Stadig's library 
>> https://github.com/pjstadig/assertions that leverages Java's `-ea` 
>> (enable-assertions, which you may want to keep enabled in dev) command-line 
>> flag. If you have a bunch of things together to assert, you may want to use 
>> the `when-assert` macro for wholesale optimization: 
>> https://github.com/pjstadig/assertions/blob/0.2.0/src/pjstadig/assertions.clj#L13
>>
>>
>> Shantanu
>>
>> On Thursday, 15 September 2016 16:50:17 UTC+5:30, joakim.t...@nova.com 
>> wrote:
>>>
>>> Ok, thanks!
>>>
>>> In the Java world, the assertions is also something that need to be turn 
>>> on explicitly.
>>> In that sence, they are kind of not mandatory to be executed (or at 
>>> least signals that to the reader of the code).
>>>
>>> I would be happier if you guys could add another method, that I can use 
>>> in my :pre conditions, that leverage
>>> the same amount of details in the error messages, but that is always 
>>> "turned on".
>>>
>>> In the meanwhile, I will use s/assert ;-)
>>>
>>> BR,
>>> Joakim Tengstrand
>>>
>>>
>>> On Wednesday, 14 September 2016 15:59:09 UTC+2, Alex Miller wrote:

 Another option that has been added since the guide was written is 
 s/assert which seems closer to what you're suggesting.

 (defn name [user]
   {:pre [(s/assert :common/user user)]}
   (-> user :user/name))

 ;; need to enable assertion checking - this can also be enabled 
 globally with system property clojure.spec.check-asserts
 (s/check-asserts true)

 (name {:user/name "Elon"})
 "Elon"

 (name {:x "Elon"})
 ExceptionInfo Spec assertion failed
 val: {:x "Elon"} fails predicate: (contains? % :user/name)
 :clojure.spec/failure  :assertion-failed
   clojure.core/ex-info (core.clj:4725)

 Rather than use it in a precondition, you can also use s/assert 
 directly in the code.

 On Wednesday, September 14, 2016 at 7:37:24 AM UTC-5, 
 joakim.t...@nova.com wrote:
>
> (ns spec-test.core
>   (:require [clojure.spec :as s]))
>
> (s/def :user/name string?)
> (s/def :common/user (s/keys :req [:user/name]))
>
> ; first version of name (using :pre)
> (defn name [user]
>   {:pre [(s/valid? :common/user user)]}
>   (-> user :user/name))
>
> ; This statement works ok and returns "Elon":
> (name {:user/name "Elon"})
>
> ; but this statement...
> (name {:x "Elon"})
>
> ;...will throw:
> CompilerException java.lang.AssertionError:
> Assert failed: (s/valid? :common/user user)
>
> ; ...but then I don't get as much information
> ; about the error as if I would have called:
> (s/explain :common/user {:x "Elon"})
>
> ;...which also contains the predicate:
> val: {:x "Elon"} fails spec: :common/user
> predicate: (contains? % :user/name)
>
> ; (second version of name - more verbose)
> ; or do I need to wite it like this:
> (defn name [user]
>   (let [parsed (s/conform :common/user user)]
> (if (= parsed ::s/invalid)
>   (throw (ex-info "Invalid input" (s/explain-data :common/user user)))
>   (-> user :user/name
>
> ; so that:
> (name {:x "Elon"})
>
> ; ...will return:
> CompilerException clojure.lang.ExceptionInfo:
>   Invalid input #:clojure.spec{:problems}
> ({:path [], :pred (contains? % :user/name),
>   :val {:x "Elon"}, :via [:common/user], :in []})
>
> ; It should be nice if I could be able to write it like this

Re: clojure.spec - Using :pre conditions (or not)?

2016-09-15 Thread joakim . tengstrand
I came up with this solution:

(ns spec-test.core
  (:require [clojure.spec :as s]))

(s/def :user/name string?)
(s/def :common/user (s/keys :req [:user/name]))

;; with this little helper function...
(defn check [type data]
  (if (s/valid? type data)
true
(throw (AssertionError. (s/explain type data)

;; I can use it in my :pre condition
(defn aname [user]
  {:pre [(check :common/user user)]}
  (-> user :user/name))

;; when I call name with an illegal arguement...
(aname {:x "Elon"})

;; ...it not fails and returns a better error message:
CompilerException java.lang.AssertionError: null, 
compiling:(/Users/joakimtengstrand/IdeaProjects/spec-test/src/spec_test/core.clj:19:1)
val: {:x "Elon"} fails spec: :common/user predicate: (contains? % :user/name)


With this solution I don't need to enable assertions, and the code is neat 
and less verbose!

/Joakim

On Thursday, September 15, 2016 at 3:11:32 PM UTC+2, Shantanu Kumar wrote:
>
> Hi Joakim,
>
> You might be interested in Paul Stadig's library 
> https://github.com/pjstadig/assertions that leverages Java's `-ea` 
> (enable-assertions, which you may want to keep enabled in dev) command-line 
> flag. If you have a bunch of things together to assert, you may want to use 
> the `when-assert` macro for wholesale optimization: 
> https://github.com/pjstadig/assertions/blob/0.2.0/src/pjstadig/assertions.clj#L13
>
>
> Shantanu
>
> On Thursday, 15 September 2016 16:50:17 UTC+5:30, joakim.t...@nova.com 
> wrote:
>>
>> Ok, thanks!
>>
>> In the Java world, the assertions is also something that need to be turn 
>> on explicitly.
>> In that sence, they are kind of not mandatory to be executed (or at least 
>> signals that to the reader of the code).
>>
>> I would be happier if you guys could add another method, that I can use 
>> in my :pre conditions, that leverage
>> the same amount of details in the error messages, but that is always 
>> "turned on".
>>
>> In the meanwhile, I will use s/assert ;-)
>>
>> BR,
>> Joakim Tengstrand
>>
>>
>> On Wednesday, 14 September 2016 15:59:09 UTC+2, Alex Miller wrote:
>>>
>>> Another option that has been added since the guide was written is 
>>> s/assert which seems closer to what you're suggesting.
>>>
>>> (defn name [user]
>>>   {:pre [(s/assert :common/user user)]}
>>>   (-> user :user/name))
>>>
>>> ;; need to enable assertion checking - this can also be enabled globally 
>>> with system property clojure.spec.check-asserts
>>> (s/check-asserts true)
>>>
>>> (name {:user/name "Elon"})
>>> "Elon"
>>>
>>> (name {:x "Elon"})
>>> ExceptionInfo Spec assertion failed
>>> val: {:x "Elon"} fails predicate: (contains? % :user/name)
>>> :clojure.spec/failure  :assertion-failed
>>>   clojure.core/ex-info (core.clj:4725)
>>>
>>> Rather than use it in a precondition, you can also use s/assert directly 
>>> in the code.
>>>
>>> On Wednesday, September 14, 2016 at 7:37:24 AM UTC-5, 
>>> joakim.t...@nova.com wrote:

 (ns spec-test.core
   (:require [clojure.spec :as s]))

 (s/def :user/name string?)
 (s/def :common/user (s/keys :req [:user/name]))

 ; first version of name (using :pre)
 (defn name [user]
   {:pre [(s/valid? :common/user user)]}
   (-> user :user/name))

 ; This statement works ok and returns "Elon":
 (name {:user/name "Elon"})

 ; but this statement...
 (name {:x "Elon"})

 ;...will throw:
 CompilerException java.lang.AssertionError:
 Assert failed: (s/valid? :common/user user)

 ; ...but then I don't get as much information
 ; about the error as if I would have called:
 (s/explain :common/user {:x "Elon"})

 ;...which also contains the predicate:
 val: {:x "Elon"} fails spec: :common/user
 predicate: (contains? % :user/name)

 ; (second version of name - more verbose)
 ; or do I need to wite it like this:
 (defn name [user]
   (let [parsed (s/conform :common/user user)]
 (if (= parsed ::s/invalid)
   (throw (ex-info "Invalid input" (s/explain-data :common/user user)))
   (-> user :user/name

 ; so that:
 (name {:x "Elon"})

 ; ...will return:
 CompilerException clojure.lang.ExceptionInfo:
   Invalid input #:clojure.spec{:problems}
 ({:path [], :pred (contains? % :user/name),
   :val {:x "Elon"}, :via [:common/user], :in []})

 ; It should be nice if I could be able to write it like this
 ; (or similar, to get a better error message):
 (defn name [user]
   {:pre [(s/explain :common/user user)]}
   (-> user :user/name))



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

Re: clojure.spec - Using :pre conditions (or not)?

2016-09-15 Thread joakim . tengstrand
Thanks for the tip!

On Thursday, September 15, 2016 at 3:11:32 PM UTC+2, Shantanu Kumar wrote:
>
> Hi Joakim,
>
> You might be interested in Paul Stadig's library 
> https://github.com/pjstadig/assertions that leverages Java's `-ea` 
> (enable-assertions, which you may want to keep enabled in dev) command-line 
> flag. If you have a bunch of things together to assert, you may want to use 
> the `when-assert` macro for wholesale optimization: 
> https://github.com/pjstadig/assertions/blob/0.2.0/src/pjstadig/assertions.clj#L13
>
>
> Shantanu
>
> On Thursday, 15 September 2016 16:50:17 UTC+5:30, joakim.t...@nova.com 
> wrote:
>>
>> Ok, thanks!
>>
>> In the Java world, the assertions is also something that need to be turn 
>> on explicitly.
>> In that sence, they are kind of not mandatory to be executed (or at least 
>> signals that to the reader of the code).
>>
>> I would be happier if you guys could add another method, that I can use 
>> in my :pre conditions, that leverage
>> the same amount of details in the error messages, but that is always 
>> "turned on".
>>
>> In the meanwhile, I will use s/assert ;-)
>>
>> BR,
>> Joakim Tengstrand
>>
>>
>> On Wednesday, 14 September 2016 15:59:09 UTC+2, Alex Miller wrote:
>>>
>>> Another option that has been added since the guide was written is 
>>> s/assert which seems closer to what you're suggesting.
>>>
>>> (defn name [user]
>>>   {:pre [(s/assert :common/user user)]}
>>>   (-> user :user/name))
>>>
>>> ;; need to enable assertion checking - this can also be enabled globally 
>>> with system property clojure.spec.check-asserts
>>> (s/check-asserts true)
>>>
>>> (name {:user/name "Elon"})
>>> "Elon"
>>>
>>> (name {:x "Elon"})
>>> ExceptionInfo Spec assertion failed
>>> val: {:x "Elon"} fails predicate: (contains? % :user/name)
>>> :clojure.spec/failure  :assertion-failed
>>>   clojure.core/ex-info (core.clj:4725)
>>>
>>> Rather than use it in a precondition, you can also use s/assert directly 
>>> in the code.
>>>
>>> On Wednesday, September 14, 2016 at 7:37:24 AM UTC-5, 
>>> joakim.t...@nova.com wrote:

 (ns spec-test.core
   (:require [clojure.spec :as s]))

 (s/def :user/name string?)
 (s/def :common/user (s/keys :req [:user/name]))

 ; first version of name (using :pre)
 (defn name [user]
   {:pre [(s/valid? :common/user user)]}
   (-> user :user/name))

 ; This statement works ok and returns "Elon":
 (name {:user/name "Elon"})

 ; but this statement...
 (name {:x "Elon"})

 ;...will throw:
 CompilerException java.lang.AssertionError:
 Assert failed: (s/valid? :common/user user)

 ; ...but then I don't get as much information
 ; about the error as if I would have called:
 (s/explain :common/user {:x "Elon"})

 ;...which also contains the predicate:
 val: {:x "Elon"} fails spec: :common/user
 predicate: (contains? % :user/name)

 ; (second version of name - more verbose)
 ; or do I need to wite it like this:
 (defn name [user]
   (let [parsed (s/conform :common/user user)]
 (if (= parsed ::s/invalid)
   (throw (ex-info "Invalid input" (s/explain-data :common/user user)))
   (-> user :user/name

 ; so that:
 (name {:x "Elon"})

 ; ...will return:
 CompilerException clojure.lang.ExceptionInfo:
   Invalid input #:clojure.spec{:problems}
 ({:path [], :pred (contains? % :user/name),
   :val {:x "Elon"}, :via [:common/user], :in []})

 ; It should be nice if I could be able to write it like this
 ; (or similar, to get a better error message):
 (defn name [user]
   {:pre [(s/explain :common/user user)]}
   (-> user :user/name))



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


Re: clojure.spec - Using :pre conditions (or not)?

2016-09-15 Thread Shantanu Kumar
Hi Joakim,

You might be interested in Paul Stadig's library 
https://github.com/pjstadig/assertions that leverages Java's `-ea` 
(enable-assertions, which you may want to keep enabled in dev) command-line 
flag. If you have a bunch of things together to assert, you may want to use 
the `when-assert` macro for wholesale 
optimization: 
https://github.com/pjstadig/assertions/blob/0.2.0/src/pjstadig/assertions.clj#L13


Shantanu

On Thursday, 15 September 2016 16:50:17 UTC+5:30, joakim.t...@nova.com 
wrote:
>
> Ok, thanks!
>
> In the Java world, the assertions is also something that need to be turn 
> on explicitly.
> In that sence, they are kind of not mandatory to be executed (or at least 
> signals that to the reader of the code).
>
> I would be happier if you guys could add another method, that I can use in 
> my :pre conditions, that leverage
> the same amount of details in the error messages, but that is always 
> "turned on".
>
> In the meanwhile, I will use s/assert ;-)
>
> BR,
> Joakim Tengstrand
>
>
> On Wednesday, 14 September 2016 15:59:09 UTC+2, Alex Miller wrote:
>>
>> Another option that has been added since the guide was written is 
>> s/assert which seems closer to what you're suggesting.
>>
>> (defn name [user]
>>   {:pre [(s/assert :common/user user)]}
>>   (-> user :user/name))
>>
>> ;; need to enable assertion checking - this can also be enabled globally 
>> with system property clojure.spec.check-asserts
>> (s/check-asserts true)
>>
>> (name {:user/name "Elon"})
>> "Elon"
>>
>> (name {:x "Elon"})
>> ExceptionInfo Spec assertion failed
>> val: {:x "Elon"} fails predicate: (contains? % :user/name)
>> :clojure.spec/failure  :assertion-failed
>>   clojure.core/ex-info (core.clj:4725)
>>
>> Rather than use it in a precondition, you can also use s/assert directly 
>> in the code.
>>
>> On Wednesday, September 14, 2016 at 7:37:24 AM UTC-5, 
>> joakim.t...@nova.com wrote:
>>>
>>> (ns spec-test.core
>>>   (:require [clojure.spec :as s]))
>>>
>>> (s/def :user/name string?)
>>> (s/def :common/user (s/keys :req [:user/name]))
>>>
>>> ; first version of name (using :pre)
>>> (defn name [user]
>>>   {:pre [(s/valid? :common/user user)]}
>>>   (-> user :user/name))
>>>
>>> ; This statement works ok and returns "Elon":
>>> (name {:user/name "Elon"})
>>>
>>> ; but this statement...
>>> (name {:x "Elon"})
>>>
>>> ;...will throw:
>>> CompilerException java.lang.AssertionError:
>>> Assert failed: (s/valid? :common/user user)
>>>
>>> ; ...but then I don't get as much information
>>> ; about the error as if I would have called:
>>> (s/explain :common/user {:x "Elon"})
>>>
>>> ;...which also contains the predicate:
>>> val: {:x "Elon"} fails spec: :common/user
>>> predicate: (contains? % :user/name)
>>>
>>> ; (second version of name - more verbose)
>>> ; or do I need to wite it like this:
>>> (defn name [user]
>>>   (let [parsed (s/conform :common/user user)]
>>> (if (= parsed ::s/invalid)
>>>   (throw (ex-info "Invalid input" (s/explain-data :common/user user)))
>>>   (-> user :user/name
>>>
>>> ; so that:
>>> (name {:x "Elon"})
>>>
>>> ; ...will return:
>>> CompilerException clojure.lang.ExceptionInfo:
>>>   Invalid input #:clojure.spec{:problems}
>>> ({:path [], :pred (contains? % :user/name),
>>>   :val {:x "Elon"}, :via [:common/user], :in []})
>>>
>>> ; It should be nice if I could be able to write it like this
>>> ; (or similar, to get a better error message):
>>> (defn name [user]
>>>   {:pre [(s/explain :common/user user)]}
>>>   (-> user :user/name))
>>>
>>>

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


Re: clojure.spec - Using :pre conditions (or not)?

2016-09-15 Thread joakim . tengstrand
Ok, thanks!

In the Java world, the assertions is also something that need to be turn on 
explicitly.
In that sence, they are kind of not mandatory to be executed (or at least 
signals that to the reader of the code).

I would be happier if you guys could add another method, that I can use in 
my :pre conditions, that leverage
the same amount of details in the error messages, but that is always 
"turned on".

In the meanwhile, I will use s/assert ;-)

BR,
Joakim Tengstrand


On Wednesday, 14 September 2016 15:59:09 UTC+2, Alex Miller wrote:
>
> Another option that has been added since the guide was written is s/assert 
> which seems closer to what you're suggesting.
>
> (defn name [user]
>   {:pre [(s/assert :common/user user)]}
>   (-> user :user/name))
>
> ;; need to enable assertion checking - this can also be enabled globally 
> with system property clojure.spec.check-asserts
> (s/check-asserts true)
>
> (name {:user/name "Elon"})
> "Elon"
>
> (name {:x "Elon"})
> ExceptionInfo Spec assertion failed
> val: {:x "Elon"} fails predicate: (contains? % :user/name)
> :clojure.spec/failure  :assertion-failed
>   clojure.core/ex-info (core.clj:4725)
>
> Rather than use it in a precondition, you can also use s/assert directly 
> in the code.
>
> On Wednesday, September 14, 2016 at 7:37:24 AM UTC-5, joakim.t...@nova.com 
>  wrote:
>>
>> (ns spec-test.core
>>   (:require [clojure.spec :as s]))
>>
>> (s/def :user/name string?)
>> (s/def :common/user (s/keys :req [:user/name]))
>>
>> ; first version of name (using :pre)
>> (defn name [user]
>>   {:pre [(s/valid? :common/user user)]}
>>   (-> user :user/name))
>>
>> ; This statement works ok and returns "Elon":
>> (name {:user/name "Elon"})
>>
>> ; but this statement...
>> (name {:x "Elon"})
>>
>> ;...will throw:
>> CompilerException java.lang.AssertionError:
>> Assert failed: (s/valid? :common/user user)
>>
>> ; ...but then I don't get as much information
>> ; about the error as if I would have called:
>> (s/explain :common/user {:x "Elon"})
>>
>> ;...which also contains the predicate:
>> val: {:x "Elon"} fails spec: :common/user
>> predicate: (contains? % :user/name)
>>
>> ; (second version of name - more verbose)
>> ; or do I need to wite it like this:
>> (defn name [user]
>>   (let [parsed (s/conform :common/user user)]
>> (if (= parsed ::s/invalid)
>>   (throw (ex-info "Invalid input" (s/explain-data :common/user user)))
>>   (-> user :user/name
>>
>> ; so that:
>> (name {:x "Elon"})
>>
>> ; ...will return:
>> CompilerException clojure.lang.ExceptionInfo:
>>   Invalid input #:clojure.spec{:problems}
>> ({:path [], :pred (contains? % :user/name),
>>   :val {:x "Elon"}, :via [:common/user], :in []})
>>
>> ; It should be nice if I could be able to write it like this
>> ; (or similar, to get a better error message):
>> (defn name [user]
>>   {:pre [(s/explain :common/user user)]}
>>   (-> user :user/name))
>>
>>

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


Re: clojure.spec - Using :pre conditions (or not)?

2016-09-14 Thread Alex Miller
Another option that has been added since the guide was written is s/assert 
which seems closer to what you're suggesting.

(defn name [user]
  {:pre [(s/assert :common/user user)]}
  (-> user :user/name))

;; need to enable assertion checking - this can also be enabled globally 
with system property clojure.spec.check-asserts
(s/check-asserts true)

(name {:user/name "Elon"})
"Elon"

(name {:x "Elon"})
ExceptionInfo Spec assertion failed
val: {:x "Elon"} fails predicate: (contains? % :user/name)
:clojure.spec/failure  :assertion-failed
  clojure.core/ex-info (core.clj:4725)

Rather than use it in a precondition, you can also use s/assert directly in 
the code.

On Wednesday, September 14, 2016 at 7:37:24 AM UTC-5, 
joakim.tengstr...@nova.com wrote:
>
> (ns spec-test.core
>   (:require [clojure.spec :as s]))
>
> (s/def :user/name string?)
> (s/def :common/user (s/keys :req [:user/name]))
>
> ; first version of name (using :pre)
> (defn name [user]
>   {:pre [(s/valid? :common/user user)]}
>   (-> user :user/name))
>
> ; This statement works ok and returns "Elon":
> (name {:user/name "Elon"})
>
> ; but this statement...
> (name {:x "Elon"})
>
> ;...will throw:
> CompilerException java.lang.AssertionError:
> Assert failed: (s/valid? :common/user user)
>
> ; ...but then I don't get as much information
> ; about the error as if I would have called:
> (s/explain :common/user {:x "Elon"})
>
> ;...which also contains the predicate:
> val: {:x "Elon"} fails spec: :common/user
> predicate: (contains? % :user/name)
>
> ; (second version of name - more verbose)
> ; or do I need to wite it like this:
> (defn name [user]
>   (let [parsed (s/conform :common/user user)]
> (if (= parsed ::s/invalid)
>   (throw (ex-info "Invalid input" (s/explain-data :common/user user)))
>   (-> user :user/name
>
> ; so that:
> (name {:x "Elon"})
>
> ; ...will return:
> CompilerException clojure.lang.ExceptionInfo:
>   Invalid input #:clojure.spec{:problems}
> ({:path [], :pred (contains? % :user/name),
>   :val {:x "Elon"}, :via [:common/user], :in []})
>
> ; It should be nice if I could be able to write it like this
> ; (or similar, to get a better error message):
> (defn name [user]
>   {:pre [(s/explain :common/user user)]}
>   (-> user :user/name))
>
>

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


Re: clojure.spec origin story

2016-09-14 Thread Andre Richards
>From clojure.spec - Rationale and overview :

Almost nothing about spec is novel. See all the libraries mentioned above, 
RDF , as well as 
all the work done on various contract systems, such as Racket’s contracts 


On Tuesday, 30 August 2016 21:36:29 UTC+1, Clark Kampfe wrote:
>
> Hi folks,
>
> I was reading David's post, A Tool For Thought 
> , and noticed 
> this bit and the paper referenced above it: "By casting validation as 
> fundamentally a parsing problem (computer science!), we get a wonderfully 
> expressive language for *crisply describing* our Clojure programs without 
> changing how we *joyfully write them*."
>
> I've been learning a lot from the paper, Parsing with Derivatives 
> , and tons more 
> from using spec.
>
> It got me curious: can anyone comment on or link to any of the other prior 
> computer science art/work/papers/libraries that has influenced spec? 
> Obviously things core.typed, plumatic schema, etc. Would love to hear from 
> folks who have worked on spec. Thanks in advance!
>
> Clark
>

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


Re: clojure.spec origin story

2016-09-02 Thread Ed Maphis
I haven't checked it myself but I remember reading that Clojure Specs were 
roughly based on Racket's Contracts.




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


Re: clojure.spec for specifying sequences of states over time

2016-08-06 Thread Timothy Baldridge
A few thoughts on your design and a possible solution to your problem.
Firstly if we are concerned about the correct ordering of values over time,
then it sounds like we are dealing with something that contains hidden
mutable state. That hidden state is a can be problematic. In general, when
working with core.async I try to encourage everyone to avoid situations
where the data received on a channel demands a specific ordering, not only
does it introduce component coupling (both sides must agree to the
protocol), but it also involves mutable state.

One possible way to spec this, however, is to express your state machine
(because that's what you have here), as a finite state machine. That is to
say, don't spec the order of events, spec the state transitions:

a -> b
b -> c
c -> d
c -> b

Each of those could be a spec, and then you could pass in both the old and
new state to each step of the state machine. In this way your state machine
remains pure, and you can spec pairs of states. I.e. an event to move to
state "d" would fail to validate if the previous state was "a".

On Fri, Aug 5, 2016 at 12:08 PM, Alex Miller  wrote:

> There are a variety of possible extensions to what is currently offered by
> spec wrt regex derivatives but that's up to Rich.
>
>
> On Friday, August 5, 2016 at 12:37:15 PM UTC-5, Russell Mull wrote:
>>
>> Suppose you have a reactive process, something that receives a message,
>> processes it, updates its, state, and repeats. For example:
>>
>> (go-loop [s :initial]
>>  (case (>:a (recur :processing)
>>:b (recur :stopping)
>>nil [:success]))
>>
>> In this contrived example, there are some implied valid state transitions:
>> :initial -> :processsing
>> :processing ->: :processing
>> :processing -> :stopping
>> :stopping -> (done)
>>
>> This is pretty easy to write as a regular expression, using clojure.spec:
>> (s/def ::state-seq
>>   (s/cat :s1 #{:initial}
>>  :s2 (s/+ #{:processing})
>>  :s3 #{:stopping}))
>>
>> But with the clojure.spec api, we'd have to store the whole sequence of
>> states and validate it once at the end. To be useful for specifying a
>> sequence of values that are spread out over time, I'd really like to be
>> able to partially evaluate the schema with a single value when it is at
>> hand. The API doesn't expose this, but the implementation appears to
>> support it. It would require the ability to track the intermediate states
>> of the regex derivative, and the ability to do an explicit complete
>> (nullable) check. It could look something like this:
>> (go-loop [st :initial, sch (s/get-spec ::state-seq)]
>>   (let [[valid sch'] (s/partial-valid? sch st)]
>> (when-not (valid)
>>   [:error "everything is terrible"]
>>   (throw "everything is terrible"))
>> (case (>   :a (recur :processing sch')
>>   :b (recur :stopping sch')
>>   nil (if (s/complete? sch')
>> [:success]
>> [:error "input channel closed, but we weren't in a done
>> state"]
>>
>>
>> This could also be useful for specifying something about the order of
>> values expected on a channel:
>> (s/def ::channel-message-seq
>>   (s/cat :s1 #{:a}
>>  :s2 (s/+ #{:b})))
>>
>> (go-loop [sch (s/get-spec ::channel-message-seq)]
>>   (let [[sch' msg] (s/partial-conform sch (> (case msg
>>   :a (recur sch')
>>   :b (recur sch')
>>   ::s/invalid [:error "got unexpected message"])))
>>
>> There are of course many convenient ways this could be packaged.
>>
>> Is it feasible or desirable to add this to clojure.spec?
>>
>> - Russell Mull
>>
> --
> 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.
>



-- 
“One of the main causes of the fall of the Roman Empire was that–lacking
zero–they had no way to indicate successful termination of their C
programs.”
(Robert Firth)

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

Re: clojure.spec for specifying sequences of states over time

2016-08-05 Thread Alex Miller
There are a variety of possible extensions to what is currently offered by 
spec wrt regex derivatives but that's up to Rich. 

On Friday, August 5, 2016 at 12:37:15 PM UTC-5, Russell Mull wrote:
>
> Suppose you have a reactive process, something that receives a message, 
> processes it, updates its, state, and repeats. For example:
>
> (go-loop [s :initial]
>  (case (:a (recur :processing)
>:b (recur :stopping)
>nil [:success]))
>
> In this contrived example, there are some implied valid state transitions:
> :initial -> :processsing
> :processing ->: :processing
> :processing -> :stopping
> :stopping -> (done)
>
> This is pretty easy to write as a regular expression, using clojure.spec:
> (s/def ::state-seq
>   (s/cat :s1 #{:initial}
>  :s2 (s/+ #{:processing})
>  :s3 #{:stopping}))
>
> But with the clojure.spec api, we'd have to store the whole sequence of 
> states and validate it once at the end. To be useful for specifying a 
> sequence of values that are spread out over time, I'd really like to be 
> able to partially evaluate the schema with a single value when it is at 
> hand. The API doesn't expose this, but the implementation appears to 
> support it. It would require the ability to track the intermediate states 
> of the regex derivative, and the ability to do an explicit complete 
> (nullable) check. It could look something like this:
> (go-loop [st :initial, sch (s/get-spec ::state-seq)]
>   (let [[valid sch'] (s/partial-valid? sch st)]
> (when-not (valid)
>   [:error "everything is terrible"]
>   (throw "everything is terrible"))
> (case (   :a (recur :processing sch')
>   :b (recur :stopping sch')
>   nil (if (s/complete? sch')
> [:success]
> [:error "input channel closed, but we weren't in a done state"
> ]
>
>
> This could also be useful for specifying something about the order of 
> values expected on a channel: 
> (s/def ::channel-message-seq
>   (s/cat :s1 #{:a}
>  :s2 (s/+ #{:b})))
>
> (go-loop [sch (s/get-spec ::channel-message-seq)]
>   (let [[sch' msg] (s/partial-conform sch ( (case msg
>   :a (recur sch')
>   :b (recur sch')
>   ::s/invalid [:error "got unexpected message"])))
>
> There are of course many convenient ways this could be packaged. 
>
> Is it feasible or desirable to add this to clojure.spec?
>
> - Russell Mull
>

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


Re: clojure.spec merge is excellent, but do you consider dissoc spec for keys?

2016-07-19 Thread Alex Miller
Well first I'd say it's actually more important here that you are reusing 
the attribute specs for ::fname ::lname etc across front and back.

And second, perhaps you should be breaking out the common parts into a spec 
you can reuse instead:

(s/def ::person-shared-spec (s/keys ::req-un [::fname ::lname]))
(s/def ::person-spec (s/merge ::person-shared-spec (s/keys ::req-un 
[::id])))
(s/def ::person-ui-spec (s/merge ::person-shared-spec (s/keys ::req-un 
[::channel])))

Or maybe you really want to combine both of these into a single spec:

(s/def ::person-spec (s/keys :req-un [(or ::id ::channel) ::fname ::lname]))

Or you could potentially use multi-spec, but I doubt you need an open spec 
for this.

We're not going to add anything like dissoc afaik.

On Tuesday, July 19, 2016 at 11:54:52 AM UTC-5, Mamun wrote:
>
> Hi 
>
> Without dissoc in keys, how to avoid duplicate spec between backend and 
> frontend layer?
>
> As an example 
>
> I have backend service where I defined spec like this 
>
> (s/def ::person-spec (s/keys ::req-un [::id ::fname ::lname]))
>
> Here Id is mandatory for some purpose. 
>
> Now application layer I would like to reuse that backend spec but only id. 
> Look like now it is not possible as there is no dissoc 
>
> As it is application layer 
>
> (s/def ::person-ui-spec (s/merge (s/keys ::req-un [::channel])
>::person-spec
>) )
>
> merge is excellent, as I could reuse exiting spec. But how I dissoc id 
> from exiting spec.
>
> Only way is now to do is define again in application layer.
>
> (s/def ::person-ui-spec (s/keys ::req-un [::channel ::fname ::lname]))
>
>
> Do you consider dissoc in spec for keys?
>
>
>
> Br,
> Mamun
> bnp paribas groups
>
>
>
>
>
>
>
>
>
>
>  
>
>

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


Re: clojure.spec and generic map with couple of special keys

2016-07-05 Thread Nikita Prokopov
That’s what I needed! Thanks

On Tue, Jul 5, 2016 at 8:15 PM gsnewmark  wrote:

> If I'm not mistaken, similar issue was recently discussed on the
> Clojurians Slack (direct link -
> https://clojurians.slack.com/archives/clojure-spec/p146738221722 ,
> archive link -
> https://clojurians-log.clojureverse.org/clojure-spec/2016-07-01.html -
> discussion starts from @ghadi's post at 17:10:00).
>
> The basic idea is to validate namespaced keywords first, remove them using
> the conformer, and then validate rest of the keys.
>
>
> On вт, лип 5, 2016 at 4:32 , Sam Estep  wrote:
>
> I ran into this same issue while trying to spec Clojure's destructuring
> language. I asked a question about this on Stack Overflow:
> http://stackoverflow.com/q/38151446/5044950
>
> On Tuesday, July 5, 2016 at 9:16:40 AM UTC-4, Nikita Prokopov wrote:
>>
>> Imagine I have a generic keyword => string map with a special key that
>> stores a number:
>>
>> { ::count 7
>>   :x "x"
>>   :y "y"
>>   :z "z"
>>   ... }
>>
>> Both cases are easy to validate on their own:
>>
>> (s/def ::count number?)
>> (s/conform (s/keys ::count) { ::count 7 })
>>
>> (s/conform (s/map-of keyword? string?) { :x "x", :y "y", :z "z" })
>>
>> But how do I write a spec to validate them when they are in a single map?
>>
>> I tried to use s/every but then another problem popped up: how do I
>> reference or check another spec from inside s/every predicate? In my case,
>> values are more complex than string? and have their own spec.
>>
>> Please help
>>
>> Nikita
>>
> --
> 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 a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/clojure/WiMV5EEAVhM/unsubscribe.
> To unsubscribe from this group and all its topics, 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.


Re: clojure.spec regression bug for 1.9.0-alpha6

2016-07-05 Thread Alex Miller
There is nothing provided or planned to do that. 

On Tuesday, July 5, 2016 at 8:43:31 AM UTC-5, Nikita Prokopov wrote:
>
> How to I make spec/fdef and regular clojure.test (not generative ones) 
> work together? I’d like for my :ret specs and HOF :ret specs to be checked 
> during regular tests. Is that possible?
>

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


Re: clojure.spec and generic map with couple of special keys

2016-07-05 Thread gsnewmark
If I'm not mistaken, similar issue was recently discussed on the 
Clojurians Slack (direct link - 
https://clojurians.slack.com/archives/clojure-spec/p146738221722 , 
archive link - 
https://clojurians-log.clojureverse.org/clojure-spec/2016-07-01.html - 
discussion starts from @ghadi's post at 17:10:00).


The basic idea is to validate namespaced keywords first, remove them 
using the conformer, and then validate rest of the keys.


On вт, лип 5, 2016 at 4:32 , Sam Estep  
wrote:
I ran into this same issue while trying to spec Clojure's 
destructuring language. I asked a question about this on Stack 
Overflow: http://stackoverflow.com/q/38151446/5044950


On Tuesday, July 5, 2016 at 9:16:40 AM UTC-4, Nikita Prokopov wrote:
Imagine I have a generic keyword => string map with a special key 
that stores a number:


{ ::count 7
  :x "x"
  :y "y"
  :z "z"
  ... }

Both cases are easy to validate on their own:

(s/def ::count number?)
(s/conform (s/keys ::count) { ::count 7 })

(s/conform (s/map-of keyword? string?) { :x "x", :y "y", :z "z" })

But how do I write a spec to validate them when they are in a single 
map?


I tried to use s/every but then another problem popped up: how do I 
reference or check another spec from inside s/every predicate? In my 
case, values are more complex than string? and have their own spec.


Please help

Nikita

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


Re: clojure.spec regression bug for 1.9.0-alpha6

2016-07-05 Thread Nikita Prokopov
How to I make spec/fdef and regular clojure.test (not generative ones) work 
together? I’d like for my :ret specs and HOF :ret specs to be checked 
during regular tests. Is that possible?

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


Re: clojure.spec and generic map with couple of special keys

2016-07-05 Thread Sam Estep
I ran into this same issue while trying to spec Clojure's destructuring 
language. I asked a question about this on Stack Overflow: 
http://stackoverflow.com/q/38151446/5044950

On Tuesday, July 5, 2016 at 9:16:40 AM UTC-4, Nikita Prokopov wrote:
>
> Imagine I have a generic keyword => string map with a special key that 
> stores a number:
>
> { ::count 7
>   :x "x"
>   :y "y"
>   :z "z"
>   ... }
>
> Both cases are easy to validate on their own:
>
> (s/def ::count number?)
> (s/conform (s/keys ::count) { ::count 7 })
>
> (s/conform (s/map-of keyword? string?) { :x "x", :y "y", :z "z" })
>
> But how do I write a spec to validate them when they are in a single map?
>
> I tried to use s/every but then another problem popped up: how do I 
> reference or check another spec from inside s/every predicate? In my case, 
> values are more complex than string? and have their own spec.
>
> Please help
>
> Nikita
>

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


Re: clojure.spec - s/and interferes with regular expressions

2016-06-29 Thread Sean Corfield
Using s/& and Mark’s fdef does “work” but the failure messages seem misleading:

 

boot.user=> (f 2 :even 4)

nil

boot.user=> (f 2 :even 3)

 

clojure.lang.ExceptionInfo: Call to #'boot.user/f did not conform to spec:

    val: () fails at: [:args :options] predicate: (& (* 
(cat :clojure.spec/k keyword? :clojure.spec/v :clojure.spec/any)) 
:clojure.spec/kvs->map (keys :opt-un [:boot.user/even])),  Insufficient input

    :clojure.spec/args  (2 :even 3)

    :clojure.spec/failure  :instrument-check-failed

 

Why Insufficient input here? Why doesn’t it point at 3 failing the ::even or 
even? predicate?

    

boot.user=> (f 2 :even 4 :odd 5)

 

clojure.lang.ExceptionInfo: Call to #'boot.user/f did not conform to spec:

    val: {:even 4, :odd 5} fails at: [:args :options] 
predicate: (fn [m] (not (contains? m :odd)))

    :clojure.spec/args  (2 :even 4 :odd 5)

    :clojure.spec/failure  :instrument-check-failed

 

This is fine: we see it fails the specific predicate provided.

    

boot.user=> (f 2 :even 4 :o 5)

nil

 

 

Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN
An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood

 

On 6/29/16, 5:07 PM, "Alex Miller"  wrote:

 

As soon as you introduce the s/and, you have dropped out of regex land and into 
a predicate. You are then matching something in a new nested regex inside the 
and like:  [[::even 4]]. To stay within the top-level regex and supply extra 
predicates, use s/& instead:

 

(s/def ::options

  (s/& (s/keys* :opt-un [::even]) (fn [m] (not (contains? m :odd)

 

user=> (s/conform ::options [:even 2])

{:even 2}

user=> (s/conform ::options [:even 2 :foo 5])

{:even 2, :foo 5}

 

user=> (s/explain ::options [:even 3])

val: () fails spec: :user/options predicate: (& (* (cat :clojure.spec/k 
keyword? :clojure.spec/v :clojure.spec/any)) :clojure.spec/kvs->map (keys 
:opt-un [:user/even])),  Insufficient input

user=> (s/explain ::options [:even 2 :odd 3])

val: {:even 2, :odd 3} fails spec: :user/options predicate: (fn [m] (not 
(contains? m :odd)))

 


On Wednesday, June 29, 2016 at 5:19:09 PM UTC-5, puzzler wrote:

I'm having trouble spec'ing out something like this, a function that takes an 
integer as an input followed by a series of optional keyworded args.  :even is 
an allowed optional keyword, but we definitely want to forbid :odd as an 
optional keyword.

(s/def ::even even?)
(s/def ::options 
  (s/and 
(s/keys* :opt-un [::even])
(fn [m] (not (contains? m :odd)

(defn f [n & {:as options}] nil)
(s/fdef f :args (s/cat :integer int? :options ::options))
(stest/instrument `f)

This doesn't work at all and gives all sorts of errors when f is called with 
any input. I believe it is because the use of s/and in the definition of 
::options interferes with the ability of ::options to be "flattened" into the 
s/cat definition.

My reasoning:

::options correctly validates [:even 2] and rejects [:even 2 :odd 3] and [:even 
3].  

If I omit the s/and and the second clause so that it reads:
(s/def ::options (s/keys* :opt-un [::even]))

this also behaves as expected.


So my conclusion is that the s/and is interfering with the ability of s/keys* 
to sit within the s/cat definition.

How does one solve this problem?

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


Re: clojure.spec - s/and interferes with regular expressions

2016-06-29 Thread Alex Miller
As soon as you introduce the s/and, you have dropped out of regex land and 
into a predicate. You are then matching something in a new nested regex 
inside the and like:  [[::even 4]]. To stay within the top-level regex and 
supply extra predicates, use s/& instead:

(s/def ::options
  (s/& (s/keys* :opt-un [::even]) (fn [m] (not (contains? m :odd)

user=> (s/conform ::options [:even 2])
{:even 2}
user=> (s/conform ::options [:even 2 :foo 5])
{:even 2, :foo 5}

user=> (s/explain ::options [:even 3])
val: () fails spec: :user/options predicate: (& (* (cat :clojure.spec/k 
keyword? :clojure.spec/v :clojure.spec/any)) :clojure.spec/kvs->map (keys 
:opt-un [:user/even])),  Insufficient input
user=> (s/explain ::options [:even 2 :odd 3])
val: {:even 2, :odd 3} fails spec: :user/options predicate: (fn [m] (not 
(contains? m :odd)))


On Wednesday, June 29, 2016 at 5:19:09 PM UTC-5, puzzler wrote:
>
> I'm having trouble spec'ing out something like this, a function that takes 
> an integer as an input followed by a series of optional keyworded args.  
> :even is an allowed optional keyword, but we definitely want to forbid :odd 
> as an optional keyword.
>
> (s/def ::even even?)
> (s/def ::options 
>   (s/and 
> (s/keys* :opt-un [::even])
> (fn [m] (not (contains? m :odd)
> 
> (defn f [n & {:as options}] nil)
> (s/fdef f :args (s/cat :integer int? :options ::options))
> (stest/instrument `f)
>
> This doesn't work at all and gives all sorts of errors when f is called 
> with any input. I believe it is because the use of s/and in the definition 
> of ::options interferes with the ability of ::options to be "flattened" 
> into the s/cat definition.
>
> My reasoning:
> ::options correctly validates [:even 2] and rejects [:even 2 :odd 3] and 
> [:even 3].  
> If I omit the s/and and the second clause so that it reads:
> (s/def ::options (s/keys* :opt-un [::even]))
> this also behaves as expected.
>
> So my conclusion is that the s/and is interfering with the ability of 
> s/keys* to sit within the s/cat definition.
>
> How does one solve this problem?
>

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


Re: clojure.spec Invalid token error from different namespace when specs are registered with number

2016-06-29 Thread Alex Miller
According to the reader page (http://clojure.org/reference/reader), keyword 
names can't start with a number. However, unqualified keywords that start 
with a number have (accidentally) worked for a long time and we have 
effectively grandfathered them in. You're seeing some of the ragged edges 
of this (which has nothing to do with spec). There is a longer history and 
a number of tickets related to this if you poke around in jira.

On Wednesday, June 29, 2016 at 9:25:41 AM UTC-5, Leon Grapenthin wrote:
>
> Have isolated more: Namespaced keywords with numbers in the name all don't 
> work, but when using double-colon syntax they can be fabricated. 
>
> :a/1 -> RuntimeException Invalid token: :a/1 
>  clojure.lang.Util.runtimeException (Util.java:221)
> :user/1 ->  RuntimeException Invalid token: :a/1 
>  clojure.lang.Util.runtimeException (Util.java:221)
>
> ::1 -> :user/1
>
>
> On Wednesday, June 29, 2016 at 4:21:49 PM UTC+2, Leon Grapenthin wrote:
>>
>> I believe that this is a problem with how the reader resolves aliased 
>> keywords as the problem can be reproduced without spec. You should file a 
>> JIRA ticket.
>>
>> On Wednesday, June 29, 2016 at 9:22:49 AM UTC+2, Mamun wrote:
>>>
>>> Hi,
>>>
>>> Invalid token error from different namespace when specs are registered 
>>> with number
>>>
>>> Example 
>>>
>>> ;one.clj
>>>
>>> (s/def ::a string?)
>>> (s/def ::1 int?)
>>>
>>> ::1  ;Ok
>>> ::a  ;Ok
>>>
>>> ;one-test.clj
>>>
>>> :one/1  ;; Error
>>> :one/a  ;;Ok
>>>
>>> ;(gen/sample (s/gen ::1))
>>> ;(gen/sample (s/gen ::a))
>>>
>>>
>>>
>>> I am not sure, it is bug or not. But error should display in same 
>>> namespace also. 
>>>
>>> Clojure version: [org.clojure/clojure "1.9.0-alpha8"]
>>>
>>>
>>> Br,
>>> Mamun
>>>
>>

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


Re: clojure.spec Invalid token error from different namespace when specs are registered with number

2016-06-29 Thread Leon Grapenthin
I believe that this is a problem with how the reader resolves aliased 
keywords as the problem can be reproduced without spec. You should file a 
JIRA ticket.

On Wednesday, June 29, 2016 at 9:22:49 AM UTC+2, Mamun wrote:
>
> Hi,
>
> Invalid token error from different namespace when specs are registered 
> with number
>
> Example 
>
> ;one.clj
>
> (s/def ::a string?)
> (s/def ::1 int?)
>
> ::1  ;Ok
> ::a  ;Ok
>
> ;one-test.clj
>
> :one/1  ;; Error
> :one/a  ;;Ok
>
> ;(gen/sample (s/gen ::1))
> ;(gen/sample (s/gen ::a))
>
>
>
> I am not sure, it is bug or not. But error should display in same 
> namespace also. 
>
> Clojure version: [org.clojure/clojure "1.9.0-alpha8"]
>
>
> Br,
> Mamun
>

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


Re: clojure.spec Invalid token error from different namespace when specs are registered with number

2016-06-29 Thread Leon Grapenthin
Have isolated more: Namespaced keywords with numbers in the name all don't 
work, but when using double-colon syntax they can be fabricated. 

:a/1 -> RuntimeException Invalid token: :a/1 
 clojure.lang.Util.runtimeException (Util.java:221)
:user/1 ->  RuntimeException Invalid token: :a/1 
 clojure.lang.Util.runtimeException (Util.java:221)

::1 -> :user/1


On Wednesday, June 29, 2016 at 4:21:49 PM UTC+2, Leon Grapenthin wrote:
>
> I believe that this is a problem with how the reader resolves aliased 
> keywords as the problem can be reproduced without spec. You should file a 
> JIRA ticket.
>
> On Wednesday, June 29, 2016 at 9:22:49 AM UTC+2, Mamun wrote:
>>
>> Hi,
>>
>> Invalid token error from different namespace when specs are registered 
>> with number
>>
>> Example 
>>
>> ;one.clj
>>
>> (s/def ::a string?)
>> (s/def ::1 int?)
>>
>> ::1  ;Ok
>> ::a  ;Ok
>>
>> ;one-test.clj
>>
>> :one/1  ;; Error
>> :one/a  ;;Ok
>>
>> ;(gen/sample (s/gen ::1))
>> ;(gen/sample (s/gen ::a))
>>
>>
>>
>> I am not sure, it is bug or not. But error should display in same 
>> namespace also. 
>>
>> Clojure version: [org.clojure/clojure "1.9.0-alpha8"]
>>
>>
>> Br,
>> Mamun
>>
>

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


  1   2   3   >