On Monday, July 6, 2015 at 3:13:21 PM UTC+2, Julian Manzano wrote: > > @ Scott, correct me if I am wrong: you say that fields of types should be > accessible only to methods in the module where the type is defined, right? > For example in Julia 0.3.10 I can write: > > module X > export myType,foo > type myType > dontTouchMe > end > foo(x::myType) = x.dontTouchMe > end >
using X z = myType(666) z.dontTouchMe # this works in 0.3.10 but you say it shoudl stop working, right? foo(z) # this works Julian > > > On Monday, July 6, 2015 at 2:42:13 PM UTC+2, Scott Jones wrote: >> >> @julian Unlike C++/Java, Julia usually doesn't do run-time dispatching >> (and when it has to, the performance can drop drastically). >> Not only that, because of the JIT nature of Julia, it can take some >> generic code, that operates on the abstract type Unsigned, for example, >> and generate different methods based on whether it is used with UInt8, >> UInt16, or UInt32. (I noticed this when writing some Unicode handling code, >> that a function that had a test something like `if ch <= 0xff ; return >> false ; elseif is_surrogate_char(ch) ; ... ; elseif ch > 0x10ffff`, in a >> loop, it actually generated >> 3 different methods, so that the UInt8 case, it simply returned false >> (which I think got inlined also into the calling function), and for the >> UInt16 case, >> it eliminated the check for ch > 0x10ffff, because Julia knew that >> 0x10ffff is greater than typemax(UInt16). >> That is what really brought home to me the power of Julia, because in >> other languages, I'd have to write the three versions myself. >> >> @mauro, I've seen no indication that fields of types are considered >> private in Julia, they are frequently accessed far away from where they are >> implemented. >> I also think, from a number of conversations at JuliaCon, that many >> people would welcome the ability to make things more disciplined. >> Remember, my proposal is for *optionally* marking a type, field, function >> or method as private to a module, so that if somebody tried to access it >> with >> Foo.privatemethod(blah) or str.privatedata, it would give a compiler (or >> run-time, if the type of str is not known at compile-time) error. >> People who don't care that anybody can fiddle with their private parts >> would just keep working exactly as they do now. >> Also, Julia already has the concept of inner and outer constructors, this >> essentially is no different, methods within a module are like >> inner constructors, they would have access to all of the "private" >> fields, functions, methods, types of the module, just as only inner >> constructors can use new(). >> That doesn't prevent you from writing methods that just use the public >> (even if not exported) types, methods, etc. to extend the interface. >> I think also that this would be a fairly simple change to make to Julia, >> that would break absolutely nothing. >> >> @julian, mangling names etc. I think just makes life more difficult for >> debugging and a lot of other things, and doesn't even get you the >> guarantees that a software engineer >> would want when trying to make show the correctness of a package. >> >> Also, saying that these "private" methods etc. are only visible within >> the module isn't really restrictive at all for the author, I've noticed >> that large modules tend to have a file at the top level >> which includes all of the files that make up the implementation, and >> exports all of the public interface, so this doesn't at all mean that one >> has to throw everything into one file. >> >> Scot >> >> On Monday, July 6, 2015 at 8:09:45 AM UTC-4, Mauro wrote: >>> >>> > Thanks a lot for your comments. >>> > >>> > @Jameson Regarding 1) I agree. Regarding point 2) Single dispatch in >>> C++ >>> > and Java is polymorphic and the type is known only at runtime: Base >>> *p; >>> > if( inputFromUser() ) p = new A; else p = new B; p->foo(). For A and >>> B >>> > subclasses of Base, p will created of type A or B at run time and >>> therefore >>> > which implementation of foo() will be called will be decided at run >>> time. >>> > Multiple dispatch in C++ and Java, same story but with a composition >>> of >>> > several dynamic single dispatches. Still do not see a significant >>> > difference apart from the convenience of avoiding method composition. >>> > >>> > Regarding point 3) I am not advocating for a solution that will >>> prevent the >>> > user from accessing fields. For me it would be nice just to see >>> something >>> > where you could at least annotate that some fields as 'internal'. In >>> this >>> > way I would know immediately what I can use and what I can not >>> (without >>> > breaking invariants or creating unnecessary coupling). As you point >>> out in >>> > Python we annotate fields with '__' and Python will mangle those names >>> so >>> > if you try to use them naively it will not work. May be in Julia we >>> could >>> > annotate a group of fields with 'internal' such that only functions >>> > annotated 'impl' can access those fields without getting warnings. >>> This is >>> > even weaker than Scott's proposal because an an owner/implementer of a >>> type >>> > you could have access to those fields even outside the module where >>> the >>> > type was defined. >>> >>> My understanding is that fields of types are considered private in Julia >>> (public is the type itself and its parameters), so really no need to >>> annotate them further (but issue #1974 makes me worry). Although >>> sometimes a underscore is used to denote functions/fields as >>> extra-private. Of course, nothing stops you to access the fields. A >>> lax approach is often taken by Julia (by choice), so I suspect it will >>> be difficult to get support for adding language features which are >>> purely there to impose discipline. >>> >>> However, there are many places in Base and elsewhere where the >>> fields-are-private is violated. Scott gave an example and here another >>> one: there is no accessor methods to get at Expr.head and Expr.args. >>> This should probably be refactored if someone has some time... >>> >>> > My two cents. >>> > Julian >>> > On Monday, July 6, 2015 at 3:15:34 AM UTC+2, Scott Jones wrote: >>> >> >>> >> >>> >> >>> >> On Sunday, July 5, 2015 at 4:24:50 PM UTC-4, Jameson wrote: >>> >>> >>> >>> Just to get it out of the way, I'll point out first that since all >>> of the >>> >>> aforementioned languages are turing-complete, they can all solve all >>> of the >>> >>> same programming problems. Therefore, there is never a question of >>> whether >>> >>> one language can be used to emulate the features of another >>> language. >>> >>> Instead, the question is whether one programming language makes the >>> right >>> >>> paradigms sufficiently more useful or obvious than another language, >>> for >>> >>> achieving the objectives of a particular programming problem. >>> >>> >>> >>> 1) OO-style dispatch is essentially single-dispatch on the first >>> >>> (implicit/hidden) argument. Multiple dispatch is a strict superset >>> of that. >>> >>> So you could provide both, but there's no benefit. It complicates >>> the >>> >>> user's mental model of the language to provide these as two >>> independent >>> >>> features, rather than one unified system. >>> >>> >>> >>> 2) In C++ and Java, the type signature of the dispatch delegate is >>> fully >>> >>> resolved at compile time. By contrast, in Julia, the dispatch occurs >>> at >>> >>> runtime, when the actual type is known. The visitor design is >>> exactly the >>> >>> sort of anti-pattern that Julia seeks to eliminate by removing the >>> forced >>> >>> distinction between multiple dispatch functions (interfaces) and >>> methods >>> >>> associated with types (ref. question #1). >>> >>> >>> >>> 3) As noted by the wikipedia article, this is a design problem, not >>> a >>> >>> language problem. Some languages, like Python and Julia, therefore >>> choose >>> >>> not to hide anything from the user, but simply provide >>> recommendations >>> >>> against certain patterns. In Julia, it is generally discouraged to >>> directly >>> >>> access the fields of an object outside some set of methods that are >>> >>> understood to be implementing the informal API for that type. >>> Similarly, in >>> >>> Python, the convention is to prefix private data with `_`, since in >>> general >>> >>> the dot-oriented access is the approved access API, but the general >>> >>> principle is the same. >>> >>> >>> >> >>> >> I agree with your first two points, and find Julia to be much more >>> >> powerful with multiple dispatch instead of single dispatch, however I >>> think >>> >> Julian's third point is something that is a problem with Julia >>> (although I >>> >> believe it could be solved, without too much trouble). >>> >> If there were a way to have functions and types (or members of types) >>> that >>> >> are not accesible outside >>> >> the module they are defined in, then one could define an interface, >>> and >>> >> not have to worry about code breaking the encapsulation. (For >>> example, >>> >> I've found hundreds of cases of accesses of .data in strings in >>> >> the registered packages, as well as others in different modules in >>> Base) >>> >> >>> >> Scott >>> >> >>> >> On Sun, Jul 5, 2015 at 3:55 PM Julian Manzano <[email protected]> >>> >>> wrote: >>> >>> >>> >>>> Hi All, >>> >>>> >>> >>>> I have been using C++ and Python for several years and I am very >>> curious >>> >>>> about Julia, I've got the REPL working on my workstation and I am >>> >>>> really impressed so far with what I've seen. >>> >>>> However there are some design decisions in the language that I fail >>> to >>> >>>> understand and I would really appreciate if someone could explain >>> the >>> >>>> rationale: >>> >>>> >>> >>>> The main point that I fail to understand is the decision not to >>> allow >>> >>>> member functions. >>> >>>> The typical explanation that I find everywhere is that Julia >>> designers >>> >>>> have chosen all the methods to be external because this is cleaner >>> >>>> (specially for mathematical methods where there is no clear owner) >>> and >>> >>>> allows for multiple dispatch. >>> >>>> This explanation does not convince me for the following reasons: >>> >>>> >>> >>>> 1) We can have multiple dispatch a la Julia and still allow types >>> to >>> >>>> have methods. These two things seeem independent to me. >>> >>>> 2) Dynamic multiple dispatch can also be done as a byproduct of >>> single >>> >>>> dispatch using the visitor pattern (C++, Java, etc.), so in that >>> sense, >>> >>>> multiple dispatch is not a new feature. >>> >>>> 3) Lack of member functions forces all field to be public and >>> therefore >>> >>>> I cannot understand how Julia will avoid the object orgy >>> anti-pattern ( >>> >>>> https://en.wikipedia.org/wiki/Object_orgy) >>> >>>> >>> >>>> But hey, Julia still looks great, it is just that I would really >>> like if >>> >>>> someone could explain away my concerns, most likely I am missing >>> something >>> >>>> here. >>> >>>> Thanks! >>> >>>> Julian >>> >>>> >>> >>> >>> >>>
