Scott: Though it has never been verbalized in the documentation most people follow the rule that fields are private. Discussions can be found in #1974. Note that for immutable the fields are(!) the interface.
In practice this concept works very well and I have not seen people that are used to Julia worry about it. Its usually only an issue for people coming from C++/Java where one has to worry about visibility. Note that visibility is not a security feature one should trust. By casting to pointers one can circumvent this in C++ Tobi Am Montag, 6. Juli 2015 14:42:13 UTC+2 schrieb Scott Jones: > > @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 <julian....@gmail.com> >> >>> 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 >> >>>> >> >>> >> >>