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 
>>>> >>>> 
>>>> >>> 
>>>>
>>>>

Reply via email to