Re: Type hints for clojure.set functions

2013-10-03 Thread Gavin Sinclair
Looks great, Andy.

-- 
-- 
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/groups/opt_out.


Re: Type hints for clojure.set functions

2013-09-30 Thread splondike
Thanks for the comment. The current behaviour is sensible for the code 
branch where the second argument is the same length or shorter than the 
first (see my first post). It is the other branch that does not do what you 
would expect. My real issue though is how the behaviour changes 
dramatically once we hit this branch (for non set args).

The original author of the 
patchhttps://github.com/clojure/clojure/commit/60e805dc7bd42b7b26fc8c8925bf71079729e0e6which
 produced this behaviour noted 
this shortcoming himself http://dev.clojure.org/jira/browse/CLJ-67, and 
only refrained from implementing the check due to being unsure about the 
performance penalty.

I think that people who are currently relying on this function working for 
non set arguments are playing a risky game (which, like me, they're 
probably not aware of) due to this sudden change in behaviour. I would 
argue that existing users would be better served by having an error thrown 
rather than having unexpected data generated which is hard to track down.

On Sunday, September 29, 2013 7:05:17 PM UTC-4, stuart@gmail.com wrote:

 I think the bar for such an enhancement is fairly high, and the value 
 delivered fairly low.  It isn't so much the impact of assessing this single 
 change, as the impact of managing the universe of such changes.

 Regards,
 Stu


-- 
-- 
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/groups/opt_out.


Re: Type hints for clojure.set functions

2013-09-30 Thread Stuart Halloway
Hi splondike,

I disagree with your arguments about what is sensible -- *any* behavior is
sensible when you violate the contract of an API.

Of course everybody could get behind the throwing the error plan if the
cost of throwing that error was zero:  zero assessment cost, zero
development cost, zero runtime cost, and zero maintenance cost.  But those
costs are not zero, so as a screener I have to ask myself should I spend
my next half hour looking at this issue, which impacts only broken
programs, or one of the (currently 20) screenable tickets, many of which
impact *correct* programs?

That said, perhaps core.typed can help us here.  I believe core.typed can
allow us to check programs and detect these kinds of errors, without
runtime impact (and without any change to Clojure at all.)  I am doing some
experiments with exactly this case, and will follow up on a separate thread.

Regards,
Stu


On Mon, Sep 30, 2013 at 2:20 PM, splondike splond...@gmail.com wrote:

 Thanks for the comment. The current behaviour is sensible for the code
 branch where the second argument is the same length or shorter than the
 first (see my first post). It is the other branch that does not do what you
 would expect. My real issue though is how the behaviour changes
 dramatically once we hit this branch (for non set args).

 The original author of the 
 patchhttps://github.com/clojure/clojure/commit/60e805dc7bd42b7b26fc8c8925bf71079729e0e6which
  produced this behaviour noted
 this shortcoming himself http://dev.clojure.org/jira/browse/CLJ-67, and
 only refrained from implementing the check due to being unsure about the
 performance penalty.

 I think that people who are currently relying on this function working for
 non set arguments are playing a risky game (which, like me, they're
 probably not aware of) due to this sudden change in behaviour. I would
 argue that existing users would be better served by having an error thrown
 rather than having unexpected data generated which is hard to track down.

 On Sunday, September 29, 2013 7:05:17 PM UTC-4, stuart@gmail.comwrote:

 I think the bar for such an enhancement is fairly high, and the value
 delivered fairly low.  It isn't so much the impact of assessing this single
 change, as the impact of managing the universe of such changes.

 Regards,
 Stu

  --
 --
 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/groups/opt_out.


-- 
-- 
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/groups/opt_out.


Re: Type hints for clojure.set functions

2013-09-30 Thread splondike
If it's a case of prioritization, that makes sense. I was going to suggest 
raising a bug, and then triaging it as low priority, but I notice that 
there is already a declined JIRA 
issuehttp://dev.clojure.org/jira/browse/CLJ-810. 
I apologize for not checking there before adding this thread.

I'm very new to Clojure which is why I wasn't sure whether this kind of 
runtime defensive programming was the norm, and you seem to suggest that 
it's not. A static checker/lint would of course be preferable if it could 
catch these kinds of programmer errors.

I notice that there's a very successful crowdsource fund going toward 
core.typed http://www.indiegogo.com/projects/typed-clojure, perhaps this 
static checker will be a reality this time next year.

On Monday, September 30, 2013 5:55:01 PM UTC-4, stuart@gmail.com wrote:

 Hi splondike,

 I disagree with your arguments about what is sensible -- *any* behavior is 
 sensible when you violate the contract of an API.

 Of course everybody could get behind the throwing the error plan if the 
 cost of throwing that error was zero:  zero assessment cost, zero 
 development cost, zero runtime cost, and zero maintenance cost.  But those 
 costs are not zero, so as a screener I have to ask myself should I spend 
 my next half hour looking at this issue, which impacts only broken 
 programs, or one of the (currently 20) screenable tickets, many of which 
 impact *correct* programs?

 That said, perhaps core.typed can help us here.  I believe core.typed can 
 allow us to check programs and detect these kinds of errors, without 
 runtime impact (and without any change to Clojure at all.)  I am doing some 
 experiments with exactly this case, and will follow up on a separate thread.

 Regards,
 Stu


 On Mon, Sep 30, 2013 at 2:20 PM, splondike splo...@gmail.comjavascript:
  wrote:

 Thanks for the comment. The current behaviour is sensible for the code 
 branch where the second argument is the same length or shorter than the 
 first (see my first post). It is the other branch that does not do what you 
 would expect. My real issue though is how the behaviour changes 
 dramatically once we hit this branch (for non set args).

 The original author of the 
 patchhttps://github.com/clojure/clojure/commit/60e805dc7bd42b7b26fc8c8925bf71079729e0e6which
  produced this behaviour noted 
 this shortcoming himself http://dev.clojure.org/jira/browse/CLJ-67, 
 and only refrained from implementing the check due to being unsure about 
 the performance penalty.

 I think that people who are currently relying on this function working 
 for non set arguments are playing a risky game (which, like me, they're 
 probably not aware of) due to this sudden change in behaviour. I would 
 argue that existing users would be better served by having an error thrown 
 rather than having unexpected data generated which is hard to track down.

 On Sunday, September 29, 2013 7:05:17 PM UTC-4, stuart@gmail.comwrote:

 I think the bar for such an enhancement is fairly high, and the value 
 delivered fairly low.  It isn't so much the impact of assessing this single 
 change, as the impact of managing the universe of such changes.

 Regards,
 Stu

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




-- 
-- 
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/groups/opt_out.


Re: Type hints for clojure.set functions

2013-09-29 Thread splondike
Thanks for the comments, you are correct that type 
hintinghttp://clojure.org/java_interop#Java Interop-Type Hintsis only to 
support performance optimization, no exceptions are thrown. The 
source for the set function suggests that it would not be free to call on 
sets, it converts its argument to a sequence and then rebuilds a set from 
that.

I tried adding a manual check based on 'instance?', and ran it through the 
old 'time clojure blah.clj' profiler (running 2*10^8 calls, 6 runs each), 
the performance penalty was lost in the noise (over ~1 minute of runtime 
per run).

Would this approach (probably with some more rigorous performance 
profiling) be something likely to be included in the language, is it 
idiomatic? 

On Saturday, September 28, 2013 4:01:10 PM UTC-4, John Hume wrote:

 On Sep 28, 2013 1:47 PM, splondike splo...@gmail.com javascript: 
 wrote:
 
  Can anyone else think of a reason why we should not add type hints to 
 the functions, or why coercing the arguments to sets is better (or 
 something else I haven't thought of)?

 IIRC, type hints are only used by the compiler to generate non-reflective 
 interop code. If you don't do interop, they have no effect. (So you won't 
 get an exception if you pass an incompatible type, unless there's a Java 
 method call in there, and I doubt clojure.set does (m)any.) 

 Iff clojure.set could call clojure.core/set on the appropriate args with 
 zero performance penalty when the arg were already a set, then I think I'd 
 want it to do so. 

 I'd guess the thinking behind the current code is if they want to do set 
 operations on their data, let them decide when and how to get that data to 
 be a set. 


-- 
-- 
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/groups/opt_out.


Re: Type hints for clojure.set functions

2013-09-29 Thread splondike
Idiomatic was probably the wrong word since we don't want to arbitrarily 
restrict options in a dynamic language. In this case where the results are 
unexpected and inconsistent in other cases, would this check be acceptable?

On Sunday, September 29, 2013 1:55:05 PM UTC-4, splondike wrote:

 Thanks for the comments, you are correct that type 
 hintinghttp://clojure.org/java_interop#Java+Interop-Type+Hintsis only to 
 support performance optimization, no exceptions are thrown. The 
 source for the set function suggests that it would not be free to call on 
 sets, it converts its argument to a sequence and then rebuilds a set from 
 that.

 I tried adding a manual check based on 'instance?', and ran it through the 
 old 'time clojure blah.clj' profiler (running 2*10^8 calls, 6 runs each), 
 the performance penalty was lost in the noise (over ~1 minute of runtime 
 per run).

 Would this approach (probably with some more rigorous performance 
 profiling) be something likely to be included in the language, is it 
 idiomatic? 

 On Saturday, September 28, 2013 4:01:10 PM UTC-4, John Hume wrote:

 On Sep 28, 2013 1:47 PM, splondike splo...@gmail.com wrote:
 
  Can anyone else think of a reason why we should not add type hints to 
 the functions, or why coercing the arguments to sets is better (or 
 something else I haven't thought of)?

 IIRC, type hints are only used by the compiler to generate non-reflective 
 interop code. If you don't do interop, they have no effect. (So you won't 
 get an exception if you pass an incompatible type, unless there's a Java 
 method call in there, and I doubt clojure.set does (m)any.) 

 Iff clojure.set could call clojure.core/set on the appropriate args with 
 zero performance penalty when the arg were already a set, then I think I'd 
 want it to do so. 

 I'd guess the thinking behind the current code is if they want to do set 
 operations on their data, let them decide when and how to get that data to 
 be a set. 



-- 
-- 
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/groups/opt_out.


Re: Type hints for clojure.set functions

2013-09-29 Thread Stuart Halloway
I think the bar for such an enhancement is fairly high, and the value
delivered fairly low.  It isn't so much the impact of assessing this single
change, as the impact of managing the universe of such changes.

Regards,
Stu

-- 
-- 
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/groups/opt_out.


Type hints for clojure.set functions

2013-09-28 Thread splondike
I just got burned by the clojure.set/difference function (v 1.5.1) wherein 
I had in error passed a vector for the second argument. This causes 
inconsistent results depending on the relative lengths of the arguments. 
That is, as soon as the second argument becomes longer than the first we 
get a different branch in the code and the behaviour changes:

user= (clojure.set/difference #{4 5} [4 5])
#{}
user= (clojure.set/difference #{4 5} [4 5 6])
#{4 5}
user= (clojure.set/difference #{:a :b} {:a 1 :b 2})
#{:a :b}
user= (clojure.set/difference #{:a :b} {:a 1 :b 2 :c 3})
#{}

What I would have liked to happen in this case is for an exception to be 
thrown, or for the second argument to be implicitly converted to a set. An 
exception is thrown if the first element is not a set, so perhaps we should 
also have that behaviour in the case of the second.

There is inconsistency for at least the union function in the face of non 
set arguments as well:
user= (clojure.set/union #{1} [1])
#{1}
user= (clojure.set/union #{1} [1 2])
[1 2 1]

I can't think of any case where the current behaviour would be desirable, 
the most relevant post I can find on the issue quoted Rich Hickey as saying 
that the behaviour of the functions on non sets should not be relied 
uponhttps://groups.google.com/d/msg/clojure/lQIP6-qJqWQ/8dFmHeXjI_gJ. 
Another posthttps://groups.google.com/d/msg/clojure/7QVFwtXWAi8/bhtkyXUWqxYJI 
read suggested (weakly) that someone had run across this behaviour and 
not found it as perverse as me.

Can anyone else think of a reason why we should not add type hints to the 
functions, or why coercing the arguments to sets is better (or something 
else I haven't thought of)?

-- 
-- 
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/groups/opt_out.


Re: Type hints for clojure.set functions

2013-09-28 Thread John D. Hume
On Sep 28, 2013 1:47 PM, splondike splond...@gmail.com wrote:

 Can anyone else think of a reason why we should not add type hints to the
functions, or why coercing the arguments to sets is better (or something
else I haven't thought of)?

IIRC, type hints are only used by the compiler to generate non-reflective
interop code. If you don't do interop, they have no effect. (So you won't
get an exception if you pass an incompatible type, unless there's a Java
method call in there, and I doubt clojure.set does (m)any.)

Iff clojure.set could call clojure.core/set on the appropriate args with
zero performance penalty when the arg were already a set, then I think I'd
want it to do so.

I'd guess the thinking behind the current code is if they want to do set
operations on their data, let them decide when and how to get that data to
be a set.

-- 
-- 
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/groups/opt_out.