>From the standpoint of performance and memory allocation (i.e., boxing), what matters is whether types are concrete, because (currently) the compiler only generates optimized code for concrete types. Anything declared to be a Union type will have the same problems as something that's type-unstable (in a sense, this is indeed the definition of type-instability).
You can test whether a type is concrete with `isleaftype`. Here's a neat example: function simplesum(A) s = 0.0 @inbounds for a in A s += a end s end Now compare code_native(simplesum, (Array{Int},)) against code_native(simplesum, (Array{Int,2},)) Also see: julia> isleaftype(Array{Int}) false julia> isleaftype(Array{Int,2}) true In other words, simply declaring a type doesn't necessarily help matters, unless that type is concrete. --Tim On Sunday, January 04, 2015 07:46:45 AM Ariel Keselman wrote: > Tim, > > in your implementation you are assuming all possible types for x implement > some operation performed inside the 'no do something with x' comment. Just > making this assumption explicit allows solving the problem in a type-stable > manner. Consider the following: > > alias NumberArray union(Array{Int64,1}, etc. could use a macro to iterate > over Number subtypes, or be defined in Base. > > function read_x_in_files(filenames) > x::Numberrray > for fn in filenames > read!(x, fn, "x") > # now do something with x > end > end > > read_x_in_files(("file1.jld", "file2.jld")) > > The above solution is just as fast (or faster) than the type-unstable one, > while being type stable, statically checkable before compilation. If the > type of x actually doesn;t support any needed opertaion the runtime error > would be raised in the 'read!' call. In the type-stable implementation it > could be raised in the exact place where you are trying to use the > unsupported operation, this could be anywhere inside the function. Here you > have a version that handles all possible error at runtime: > > function read_x_in_files(filenames) > x::Numberrray > for fn in filenames > try > read!(x, fn, "x") > catch typeerror > message("skipping file "*fn*" because it contains an > incompatible type") > continue > end > # now do something with x > end > end > > > Doing the same today is harder. Another solultion would be to just keep it > type unstable inside a global scoped macro instead of a function, or inside > a function tagged as type unstable. > > Mike, > > What is so special about Markdown.jl? I know of Markdown parsers > implemented in statically typed languages (all 100% type stable) which are > small, efficient and flexible. See for e.g. > https://github.com/mfp/ocsiblog/blob/more-markdown-compat/simple_markup.ml > which uses ~250 LOCs for parsing and another ~50 for rendering to HTML. Its > said to be faster than discount which is written in C. Also how compliant > is the Markdown.jl implementation? There are many shortcuts you can do to > increase performance and code size/simplicity vs fully correct behavior. I > know of a few fast parsers which seem type stable, for e.g. Python mistune, > here: http://mistune.readthedocs.org/en/latest/ > Anyway, the fastest Markdown must be sundown? (what github uses is based on > this one) its fully compatible, and type stable, and its 2K lines but in C. > I could simply traslate one of those, or even your implementation. I did > skimmed it coarsely but didn't find any obvious type instabilities > anyway... these can be hard to find even using tools > > Now I guess I'll just conclude my point like this: > > Type instability isn't really about speed. It's about reliably being able > to modify your program when it gets bigger. At work (a corporate one) I was > once promoting the use of Python, and I was always demonstrating how it is > fast enough. I presented Numba, Cython, IO bound applications, etc. It took > me a long time to understand that what people were really looking for is > type-checks. its like an always sync'd documentation. It enables efficient > refactoring, it compliments testing. > > I don't like the terms 'dynamic' and 'static' to describe languages. I much > prefer 'interactive' and 'stable typed'. These seem more orthogonal > concepts. In fact stable typed languages could still be interactive, and > please don't think they are not flexible. We still have multiple dispatch, > macros, eval at global scope, etc. > > I think Julia is very good just as it is now, and it allows for many static > checks to be performed, at least way more than other "dynamic" (or > "interactive") languages) like Python allow. > > Just please lets keep type instability to a minimum within the language and > standard library. Lets also actively encourage type stability, all within > the reasonable of course :) Can we all agree on this?