Thank you all for making the matter clearer. I will use comments/notation to separate interface from implementation. Julian
On Monday, July 6, 2015 at 4:29:00 PM UTC+2, Scott Jones wrote: > > I need a bit more reliability and security than that (remember, we want to > be able to write applications for hospitals!). > The problem is, how are you going to police all of the _ accesses, to give > somebody crap about it? > Are you going to have to grep all of the registered packages constantly? > I think that the tools need to be in place, so that people who need to > control access, can do so. > It won't make a bit of difference to people who don't care about it, so > why not have it? > > On Monday, July 6, 2015 at 10:18:23 AM UTC-4, Tom Breloff wrote: >> >> I personally find underscores to be plenty good as "private" indicators. >> Yes people may still reach in and access those fields directly, but I bet >> they'll hesitate a little bit, which is all I ask. I certainly do NOT want >> to force people to jump through extra hoops (boilerplate code), but >> establishing good practice as a community is valuable. If someone submits >> a pull request that accesses a field with an underscore directly, give them >> crap about it. If there's a good reason: add comments, add tests, and make >> sure someone is ready to maintain it. >> >> On Monday, July 6, 2015 at 9:37:59 AM UTC-4, Scott Jones wrote: >>> >>> >>> >>> On Monday, July 6, 2015 at 9:23:22 AM UTC-4, andrew cooke wrote: >>>> >>>> >>>> i feel like these conversations are often driven by people who want >>>> "new language" to be like whatever language they are most familiar with. >>>> and those people, since they are naturally in an uncomfortable place (away >>>> from their "old" language) tend to be the most vocal. >>>> >>> >>> No, my proposal is just about adding an *extra* capability, which is >>> necessary if you want to be able to make any sorts of guarantees about >>> about separation of interfaces from implementations. >>> As I've already seen a lot of evidence that the "consenting adults" >>> approach is not working in many cases, and there is frequent breakage when >>> anybody changes something inside their module/package, >>> not expecting that somebody else has used some internal function (I just >>> got bit by this last week, because the JSON.jl package was using two >>> undocumented and unexported functions that were defined in utf16.jl. >>> Those were not really safe to be called externally, because they make >>> certain assumptions about the type of the arguments, but since julia has no >>> way of marking something as private, and people consistently ignore that >>> something is not part of the interface, breakage occurred. >>> >>> >>>> so i just wanted to add a voice saying, no. i don't want this. i >>>> think the initial design of the language was correct. the added complexity >>>> here seems unnecessary to me. things work just fine in more functional >>>> languages that do not have this kind of constraint. they also work fine >>>> in >>>> python - if you want to use underscores in names as a sign to others, go >>>> ahead. >>>> >>> >>> underscores in names, and name mangling, is no solution, because people >>> will just ignore that if they want to. >>> Remember, my idea would NOT change any current code, just allow >>> programmers who *need* to have things more disciplined to be able to do so. >>> >>> >>>> more than that, there are more important problems still to be >>>> addressed. inheritance of fields, for example. >>>> >>> >>> Being able to make secure, reliable programs in Julia I think is one of >>> the most important issues, if julia is ever going to be used in real >>> critical code. >>> Inheritance of fields sounds like something where you want "new >>> language" to be like some other language. >>> >>> >>>> >>>> andrew >>>> >>>> >>>> On Monday, 6 July 2015 09:42:13 UTC-3, 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 >>>>>> >>>> >>>>>> >>> >>>>>> >>>>>>
