Stefan: I agree that typing Distributions.Normal(0,1) in the REPL when you're just doing data exploration is really frustrating. However, when you're building a package or a larger system, it can be really important to either explicitly qualify your types/functions or to explicitly "import Distributions: Normal". Frequently I'll be looking at some code within a large package with a call to "Normal", but I don't know what function will be called here. If I do some type of explicit importing, then I can do a simple find command on my directory to figure out what package it may have been defined in. If I did a "using", then I have a lot more searching to figure out the correct function. Not to mention the silent overwriting of functions by "using" different modules can cause unexpected problems. For that reason, I try to keep "using" to an absolute minimum in most of my code.
On Wednesday, April 29, 2015 at 2:49:34 PM UTC-4, Stefan Karpinski wrote: > > This scheme seems overly focused on object-oriented programming styles at > the cost of making other programming styles much more inconvenient. In an > o-o language that might be fine, but non-o-o styles are quite common in > Julia. The `connect` example keeps coming up because it is one of those > cases where o-o works well. That is not the norm in numerical package, > however. This proposal would, for example, make using Distributions > <https://github.com/JuliaStats/Distributions.jl> a nightmare – you'd have > to explicitly import almost everything that it exports > <https://github.com/JuliaStats/Distributions.jl/blob/dacb401cfcfc7463f69af0009497960038b25dd5/src/Distributions.jl#L18-L238> > to > use. That includes type constructors for distributions etc., since those > are themselves (basically) generic functions and their arguments are just > built-ins. Instead of doing this: > > using Distributions > X = Normal(0.0, 1.0) > p = pdf(X, 0.1) > > > you'd have to do this: > > using Distributions > X = Distributions.Normal(0.0, 1.0) > p = Distributions.pdf(X, 0.1) > > > Or you'd have to explicitly import every Distributions type and generic > stats function that you want to use. Instead of being able to write `using > Distributions` and suddenly having all of the stats stuff you might want > available easily, you'd have to keep qualifying everything or explicitly > importing it. Both suck for interactive usage – and frankly even for > non-interactive usage, qualifying or explicitly importing nearly every name > you use is a massive and unnecessary hassle. > > On Wed, Apr 29, 2015 at 2:06 PM, Michael Francis <[email protected] > <javascript:>> wrote: > >> I would expect the user to explicitly import those method, I did not >> preclude their existence. And it would be quite reasonable to support the >> existing import all syntax hence >> >> using MyModule >> ^ imports only those functions which explicitly reference user types >> defined in the module >> importall MyModule.Extensions >> ^imports the additional functionality on base types >> >> if I subsequently import another function which conflicts then we throw >> an error. This would mean that the vast majority of non conflicting >> functions can be trivially exported and used without a namespace qualifier >> and extensions to base types would also work, but with the name collision >> check in place. >> >> I don't believe this violates the expression problem ? >> >> >> On Wednesday, April 29, 2015 at 1:55:14 PM UTC-4, Stefan Karpinski wrote: >>> >>> >>> I made the point at the outset that it isn't hard (or expensive) if the >>> *exported >>>> *functions from a module *must reference types defined in that module*. >>>> Hence the suggestion that module developers should only be able to export >>>> functions which reference owned/hard/contained/user types. >>>> >>> >>> Unless I'm misunderstanding, this is a very limiting restriction. It >>> would mean, for example, that you can't define and export a generic >>> square(::Number) function. That's a silly example, but it's completely >>> standard for packages to export new functions that operate on pre-existing >>> types that don't dispatch on any type that "belongs" to the exporting >>> module. >>> >>> Another way of looking at this is that such a restriction would prevent >>> solving half of the expression problem >>> <http://en.wikipedia.org/wiki/Expression_problem>. In object-oriented >>> languages, extending existing operations to new types is easily done via >>> subtyping, but adding new operations to existing types is awkward or >>> impossible. In functional languages, adding new operations to existing >>> types is easy, but extending existing operations to new types is awkward or >>> impossible. Multiple dispatch lets you do both easily and intuitively – so >>> much so that people can easily forget why the expression problem was a >>> problem in the first place. Preventing the export of new functions >>> operating only on existing types would hobble the language, making it no >>> more expressive than traditional object-oriented languages. >>> >> >
