Hello, Because this Jira hasn’t gotten much traction over the last few days, I figured that I’d bubble the discussion up to the dev list to try to prompt more comments. The discussion thread follows below for convenience.
Cheers, -Rob ------------------------ Description This is a follow-up of a discussion held in TEXT-34. IMHO, there is no harm in depending on the "commons-rng-client-api" module of Commons RNG; the "zero dependency" mantra does not hold here, since TEXT already depends on LANG. OTOH, I see that it is counter-productive (i.e. it harms the Commons project as a whole) to not advertize or use other Commons components, despite the "own dog food" phrase appearing recurrently on the "dev" ML. Rather than having people blindly use java.util.Random, we should allow them to choose wisely, based on full information. IMO, that means to indeed use UniformRandomProvider in order to raise awareness about alternatives to the sub-optimal algorithm used by the JDK. However, if some Commons developers do not trust that the UniformRandomProvider interface can be stable enough for TEXT, then we should follow Jochen Wiedemann's advice (cf. archive of the "dev" ML) and define TEXT's own interface to random numbers, with bridges to it from UniformRandomProvider and from java.util.Random. Comments Comment by Gary Gregory [ 21/Dec/16 ] I can see a best of both worlds here based on your description. TEXT provides a random interface with 2 implementation: one to Java own random with a red waving flag on it and another impl based on RNG. Comment by Bernd Eckenfels [ 21/Dec/16 ] I would stick with the java.util.Random signature, if you want to specify a different random Generator you can subclass j.u.Random and overwrite protected int next(int). In fact I would exepect RNG to provide such an Adapter already. Advantage is, that no dependency of TEXT to RNG is needed. Comment by Duncan Jones [ 22/Dec/16 ] It would be good to hear why people are concerned about a link between TEXT and RNG. Is it a fear of Maven jar hell? I.e. TEXT depends upon a specific version of RNG, which clashes somehow with the preferred version of the user's code? If that's the concern, then I don't think Gregory's suggestion saves us anything, since we'd have to depend upon RNG to offer the interface. IMO, the four options I can see in descending order of preference are: Eat our own dog food - use RNG as the only visible option. Users can bridge to java.util.Random using RNG's bridge classes if they must. As above, but explicitly offer overloads with java.util.Random. Offer only java.util.Random in the interface, but shade RNG so that our internal default implementations are as good as can be. Don't use RNG at all. Comment by Gilles [ 22/Dec/16 ] It would be good to hear why people are concerned about a link between TEXT and RNG. +1 Indeed, are there technical objections? There is nothing in favour of using the JDK's Random class in new applications (or libraries such as TEXT): no speed of generation advantage, no quality of randomness advantage, no memory consumption advantage. Over the course of developing what has become Commons RNG, I've made a summary of why not to use java.util.Random. The only justification for using it is when applications are required to reproduce the same sequence as the particular algorithm implemented by Random (needless to say: It is not the most obvious case for "randomness"). Is it a fear of Maven jar hell? This would be bogus, given that we don't release code that could create it (due to the change of package name and coordinates). Eat our own dog food +1 IOW tell the world to come and taste it too. And grow the community... Users can bridge to java.util.Random using RNG's bridge classes Not sure what you mean. JDKRandomBridge is a bridge from Commons RNG's RandomSource to JDK's Random (so not applicable to pass to a TEXT API based on Commons RNG). A user who would want to use Random as the underlying generator would create the corresponding UniformRandomProvider. explicitly offer overloads with java.util.Random. This is what Gary proposes. Thus, assuming a TextRandomProvider interface: import java.util.Random; public class JdkRandomBridge implements TextRandomProvider { private final Random delegate; public JdkRandomBridge(Random rng) { delegate = rng; } // TextRandomProvider methods. /** {@inheritDoc} */ public int nextInt(int min, int max) { // Generate an integer in range [min, max]. return delegate.nextInt(max + 1) + min; } } import org.apache.commons.rng.UniformRandomProvider; public class CommonsRngBridge implements TextRandomProvider { private final UniformRandomProvider delegate; public CommonsRngBridge(UniformRandomProvider rng) { delegate = rng; } // TextRandomProvider methods. // ... } Offer only java.util.Random in the interface, but shade RNG so that our internal default implementations are as good as can be. This does not look good: Users who care about the source of randomness are stuck with a sub-par algorithm, while users who don't care get a better one... Moreover, as a general remark, I'm -0 on "hiding" a fundamental parameter of some functionality (here, the RNG for building random strings). Don't use RNG at all. Does not make any sense. Comment by Rob Tompkins [ 26/Dec/16 ] Bernd's comment seems like a really good pattern with regards to consuming other components, extending existing java classes/interfaces with our own implementations with the idea that the examples provided display using the other component. In doing this we give consumers more control over precisely the dependencies that they desire when running their applications. Either way, though, I'm in the +/- 0 category. So I'd say don't spend too much time worrying about my opinion here. Comment by Gilles [ 26/Dec/16 ] a really good pattern Depends on what you consider to be the pattern: reuse is good (in general), reuse of java.util.Random as an interface/base class is bad (in particular). control over precisely the dependencies that they desire This is only one aspect of things. Even so, still waiting for answers as to why a dependency on RNG must be avoided (at all cost)... Comment by Rob Tompkins [ 26/Dec/16 ] Fair. I was just thinking of how to give the consumer the most options. Comment by Gilles [ 26/Dec/16 ] how to give the consumer the most options By implementing a custom interface (exemplified as TextRandomProvider above).