Your response ignores my strong example. And "not declare types in function 
signatures" does not "work just fine most of the time," because multiple 
dispatch largely breaks if you don't type your arguments. You simply must 
type your function arguments for Julia to be able to resolve the right 
method for each ambiguous function.

On Sunday, May 25, 2014 6:23:39 PM UTC-4, Mauro wrote:
>
> On Sun, 25 May 2014 14:11:41 -0700 (PDT), Adam Smith wrote: 
> > Actually, no. I'm not going to pretend this is a good thing. You're 
> right 
> > that it is "consistent and logical" when you're using an academic 
> > type-correctness viewpoint. However, it is not consistent from a 
> developer 
> > perspective, and here's why. 
>
> Well, it's not a good thing in kinda the same way that π = 
> 3.1415926535897...  It would be much more convenient if π = 3, but that 
> just does not work. 
>
> The way around dealing with this problem is not not declare types in 
> function signatures which works just fine most of the time.  If one needs 
> to declare parametric types then one needs to be aware of some of the 
> intricacies of the type system.  For instance that parametric types are 
> invariant: 
>
> http://docs.julialang.org/en/latest/manual/types/#parametric-composite-types 
>
> On Sun, 25 May 2014 14:11:41 -0700 (PDT), Adam Smith wrote: 
> > Actually, no. I'm not going to pretend this is a good thing. You're 
> right 
> > that it is "consistent and logical" when you're using an academic 
> > type-correctness viewpoint. However, it is not consistent from a 
> developer 
> > perspective, and here's why. 
> > 
> > On most functions, I don't need to specify parametric types (which is 
> good: 
> > there is less clutter). Let's say I have a function: 
> > function output(context::Context, string::String) 
> >     context.something() 
> >     println(string) 
> > end 
> > 
> > output(context, "Hi there") 
> > 
> > And a few days later I decide it would be better to accept a list of 
> > strings instead, so I do the most natural thing, and I just put Vector{} 
> > around the type that was already working: 
> > 
> > function output(context::Context, strings::Vector{String}) 
> >     context.something() 
> >     for string in strings println(string) end 
> > end 
> > 
> > output(context, ["Hi there"]) 
> > 
> > This is absolutely what every new Julia developer will expect to work 
> > (regardless of how "correct" it is), and it will fail. It's especially 
> > confusing because for some types, it works (like changing Int to 
> > Vector{Int}). It is simply bizarre to new developers using the language 
> > that the type matching worked on a single element of that type, but not 
> on 
> > a parametric collection of that type. 
> > 
> > Yes, I know why it is the way it is, and yes, I know why a textbook says 
> it 
> > should be this way, but thinking from a UX perspective (where the "user" 
> is 
> > a developer new-ish to Julia), it's quite off-putting. 
> > 
> > On Sunday, May 25, 2014 1:50:19 PM UTC-4, Adam Smith wrote: 
> > > 
> > > You're right, that's not bad at all. Thanks. 
> > > 
> > > On Sunday, May 25, 2014 12:41:04 PM UTC-4, Iain Dunning wrote: 
> > >> 
> > >> julia> f{T<:String}(strs::Vector{T}) = dump(strs) 
> > >> f (generic function with 1 method) 
> > >> 
> > >> julia> f(["foo"]) 
> > >> Array(ASCIIString,(1,)) ASCIIString["foo"] 
> > >> 
> > >> 
> > >> Seems fine to me, and more importantly (to me), is consistent and 
> > >> logical. Vector{String} is a concrete type, its a specific thing. 
> > >> Vector{T},T<:String, is the family of vectors that contain String-y 
> things. 
> > >> Unless you are writing library code, not much point to getting trick 
> with 
> > >> type signatures anyway - there is no speed benefit to doing so, its 
> just a 
> > >> defensive programming thing. 
> > >> 
> > >> 
> > >> On Sunday, May 25, 2014 12:23:34 PM UTC-4, Adam Smith wrote: 
> > >>> 
> > >>> I'd just like to add that this behavior is a real downer when 
> dealing 
> > >>> with strings, too. During testing/debugging inline strings are 
> > >>> ASCIIStrings, but I don't want to hardcode my functions to use 
> ASCIIStrings 
> > >>> (or have to make Unions absolutely every place I want a vector of 
> strings): 
> > >>> 
> > >>> julia> f(strs::Vector{String}) = dump(strs) 
> > >>> f (generic function with 1 method) 
> > >>> 
> > >>> julia> f(["foo"]) 
> > >>> ERROR: no method f(Array{ASCIIString,1}) 
> > >>> 
> > >>> julia> g(strs::Vector{UTF8String}) = dump(strs) 
> > >>> g (generic function with 1 method) 
> > >>> 
> > >>> julia> g(["foo"]) 
> > >>> ERROR: no method g(Array{ASCIIString,1}) 
> > >>> 
> > >>> julia> h(strs::Vector{ASCIIString}) = dump(strs) 
> > >>> h (generic function with 1 method) 
> > >>> 
> > >>> julia> h(["foo"]) 
> > >>> Array(ASCIIString,(1,)) ASCIIString["foo"] 
> > >>> 
> > >>> 
> > >>> 
> > >>> On Sunday, May 25, 2014 11:46:43 AM UTC-4, Pierre-Yves Gérardy 
> wrote: 
> > >>>> 
> > >>>> 
> > >>>> 
> > >>>> On Sunday, May 25, 2014 5:44:26 PM UTC+2, Pierre-Yves Gérardy 
> wrote: 
> > >>>>> 
> > >>>>> On Sunday, May 25, 2014 5:10:49 PM UTC+2, James Crist wrote: 
> > >>>>>> 
> > >>>>>> Yeah, that's what I've been using. My issue with it is that the 
> > >>>>>> declarations get long for functions with more than 2 arrays. Was 
> hoping 
> > >>>>>> there was a more concise way. 
> > >>>>>> 
> > >>>>> 
> > >>>>> You can use  typealias Fp FloatingPoint , then 
> > >>>>> 
> > >>>>   
> > >>>> ... or  Fp = FloatingPoint , types are first class objects. 
> > >>>>   
> > >>>> 
> > >>>>>   
> > >>>>> 
> > >>>> function foo{T1<:Fp, T2<:Fp}(a::Array{T1}, b::Array{T2}) 
> > >>>>> 
> > >>>>> 
>
>
>

Reply via email to