... and the ModInt example is fixed again: julia> include("examples/modint.jl") showcompact (generic function with 8 methods)
julia> A = map(ModInt{11}, rand(1:1000,5,5)) 5x5 Array{ModInt{11},2}: 10 1 6 5 1 10 9 6 10 8 2 9 2 1 6 10 4 3 2 8 6 5 2 3 10 julia> B = map(ModInt{11}, rand(1:1000,5,5)) 5x5 Array{ModInt{11},2}: 3 9 8 5 5 2 4 5 3 9 4 3 0 7 9 2 3 9 2 2 0 9 4 5 10 julia> A*B 5x5 Array{ModInt{11},2}: 0 4 2 0 1 4 4 5 3 10 1 7 6 6 6 10 6 7 6 10 9 3 8 5 1 julia> 2A^5 - 3B + 2I 5x5 Array{ModInt{11},2}: 1 1 1 0 2 4 6 10 7 5 6 4 2 1 8 3 2 9 4 9 1 9 10 7 3 You might also want to check out this presentation on the design impact of multiple dispatch: http://nbviewer.ipython.org/gist/StefanKarpinski/b8fe9dbb36c1427b9f22 The interval arithmetic examples are a bit broken because I unwisely hacked the parser to make them a bit nicer (thinking that I'd then make the changes permanent, which I didn't), but that's just a matter of syntax. On Tue, Apr 8, 2014 at 12:23 AM, Jeff Bezanson <jeff.bezan...@gmail.com<https://mail.google.com/mail/?view=cm&fs=1&tf=1&to=jeff.bezan...@gmail.com> > wrote: > Short answer: if a user adds a method to `Base.setindex!`, it *will* > be accessible to library code. > > The difference from python here is that python has a single namespace > of method names: if your object has a method `__setitem__`, *all* > python code that says `x[...]=...` might call it. In julia, you can > have a totally separate `setindex!` function with methods for your > types, which no other code knows about. Or you can extend the standard > `Base.setindex!`. > > > On Mon, Apr 7, 2014 at 11:51 PM, Stefan Karpinski > <ste...@karpinski.org<https://mail.google.com/mail/?view=cm&fs=1&tf=1&to=ste...@karpinski.org>> > wrote: > > I'm a little confused about what you feel is missing. You can do duck > typing > > just as well as in any dynamic language. While it's true that there > aren't > > explicit interfaces (or protocols or concepts), those don't exist in > Python > > either. Julia's abstract types give you everything that > > interfaces/protocols/concepts do except for (a) multiple inheritance and > (b) > > the ability to explicitly require the implementation of certain methods. > > > > A couple of examples of informal protocols that are used all the time in > > Julia and allow user defined types to easily hook into predefined generic > > behaviors are the start/done/next protocol for iteration and the order > and > > sort! protocols ordering and sorting things. The ModInt example shows > that > > if you just define addition and multiplication for a new user-defined > > numeric type, you can immediately construct matrices of that type and > > multiply them (unfortunately, this example is currently broken). > > > > I can't think of any languages where user defined types are as first > class > > as they are in Julia. As Jameson noted, there is almost no distinction - > > most "built in" types are really just user defined types that are defined > > for you. Even basic types like integers are defined in Julia and given > all > > of their behaviors in Julia. Even in Scheme, integers and their behavior > are > > built in. > > > > Is it the lack of multiple inheritance that's throwing you? Lack of > formal > > specifications for protocols? The fact that generic functions live > outside > > of types? > > > > > > On Mon, Apr 7, 2014 at 10:43 PM, Jameson Nash > > <vtjn...@gmail.com<https://mail.google.com/mail/?view=cm&fs=1&tf=1&to=vtjn...@gmail.com>> > wrote: > >> > >> In Julia there is (almost) no distinction between user-defined > >> functions and library code. In fact, an increasing percentage of the > >> "library" code is just pre-packaged Julia functions that happen to > >> live in the Base module ('increasing', because stuff often moves from > >> C to Julia because doing so doesn't sacrifice speed but does it more > >> flexible, such as Stefan's recent work with fast hashing). All code is > >> equally able to provide an implementation of the Base.setindex! > >> function > >> > >> Note that if you define a new function Main.setindex! without first > >> importing Base.setindex!, you will create a new function. Similar > >> name, but completely separate > >> > >> similarly, backend output swapping is implemented using MIME types in > >> the Base.display function > >> > >> users can either derive from an abstract class you provide (explicit > >> inheritance), or you can define your function to take an object of > >> type Any (duck typing) > >> > >> On Mon, Apr 7, 2014 at 10:28 PM, Mason McGill > >> <mason.b.mcg...@gmail.com<https://mail.google.com/mail/?view=cm&fs=1&tf=1&to=mason.b.mcg...@gmail.com> > > > >> wrote: > >> > The issue is that user-defined functions (in this case, `setindex!`) > >> > aren't > >> > accessible from library code. in Python, you can have something like > >> > this: > >> > > >> > # module A > >> > def zero(x): > >> > x[:] = 0 > >> > > >> > # module B > >> > class C: > >> > def __setitem__(self, key, value): > >> > print("Perform custom behavior here") > >> > > >> > from A import zero > >> > zero(C()) > >> > > >> > But it doesn't look like there's an idiomatic way to do that in Julia, > >> > meaning you couldn't really implement something like the C++ STL or D > >> > ranges. Some less trivial examples of where this kind of polymorphism > >> > is > >> > important: > >> > - I have 10 classes of pedestrian detectors to test. They all have > the > >> > same > >> > "interface" but are implemented differently. I want to use the test > >> > function my coworker wrote, without having to modify it. > >> > - I'm building a graphical application and I want to be able to swap > the > >> > back-ends (e.g. Qt and HTML) with a single function call. > >> > - I'm writing an image processing library and I'd like users to be > able > >> > to > >> > work with their own data types (like stereo image or spatial pyramid), > >> > so > >> > long as those types support fundamental operations (like indexing). > >> > > >> > I hope this clears things up! > >> > > >> > On Monday, April 7, 2014 5:38:03 PM UTC-7, Keno Fischer wrote: > >> >> > >> >> I am unsure as to what your question is. I would probably write the > >> >> above > >> >> as: > >> >> > >> >> zero!{T}(x::AbstractArray{T}) = fill!(x,zero(T)) > >> >> > >> >> but the way you wrote it works just fine assuming `setindex!` is > >> >> defined > >> >> correctly. > >> >> > >> > > > > > >