Although Python gets by fine without any enforced privacy, Python is also 
notorious for being poorly suited for writing large scale reliable systems 
- lack of privacy of internals is only one factor among many, but it 
contributes.

However this will be very difficult to convince enough of the core 
development group that it needs to be implemented (hint: step one is to 
create a proof-of-concept implementation) as a first-class language 
feature, when it could potentially be implemented via macros in user code. 
Especially on top of getfield overloading, #1974.

P.S: Scott, for everyone's benefit, please refrain from using the "private 
parts" metaphor.


On Wednesday, July 8, 2015 at 8:47:50 AM UTC-4, Tom Breloff wrote:
>
> So after lots of internal back and forth, I think I'm firmly in the camp 
> that we DO NOT need additional syntax to restrict field access.  If you 
> want something to be private, use an underscore, and be harsh on people 
> that access it directly.  You can't protect other people from writing bad 
> code... they will always find a way.  Making development a chore to protect 
> others from their own stupidity is something I can't get behind.  I'm 
> coming from 20 years of object oriented mindset, and so I completely 
> understand Scott's feelings that internal changes are safer when internals 
> are only accessed by getter/setter methods.  That may be true, but it 
> sucks.  The absolute worst part about the getter/setter style is the 
> horrible verbose codebase that does so little with so much code.  It's less 
> maintainable because structural changes have far reaching consequences 
> (except in the very simple/rare case where you swap out the field's type 
> without changing the interface, which btw should be handled seamlessly by 
> Julia in many cases).  
>
> My solution: make sure there is a clear and public declaration of "Julia 
> standards" so that people can understand intentions from other's code 
> (underscores indicating private fields for example), and employ public 
> shame when package developers break the social code. 
>
> On Wednesday, July 8, 2015 at 8:05:00 AM UTC-4, Julian Manzano wrote:
>>
>> Problem is, some fields for some cases should be public, because this is 
>> the most natural option...
>>
>> On Wednesday, July 8, 2015 at 1:56:37 PM UTC+2, Milan Bouchet-Valat wrote:
>>>
>>> Le mercredi 08 juillet 2015 à 12:37 +0200, Stefan Karpinski a écrit : 
>>> > On Sun, Jul 5, 2015 at 7:30 PM, Julian Manzano < 
>>> > [email protected]> wrote: 
>>> > > Hi All, 
>>> > > 
>>> > > I have been using C++ and Python for several years 
>>> > > 
>>> > I'll comment on this later... 
>>> >   
>>> > > 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. 
>>> > > 
>>> > Thanks :-) 
>>> >   
>>> > > 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. 
>>> > > 
>>> > These things are distinct but not orthogonal. Multiple dispatch is a 
>>> > generalization of single dispatch. As such, it is strictly more 
>>> > expressive, and having two separate dispatch mechanisms – a weak one 
>>> > for "internal" methods and a more powerful one for external methods – 
>>> > would be non-orthogonal while not increasing the overall expressive 
>>> > power of the language at all. That's lose-lose from a language design 
>>> > perspective. 
>>> >   
>>> > > 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. 
>>> > > 
>>> > This isn't really true – or at least double dispatch requires an 
>>> > unacceptable amount of coupling between classes that should be 
>>> > unrelated to emulate proper multiple dispatch. This article has a 
>>> > pretty lucid explanation of the issues. In particular note the bit 
>>> > about the price of double dispatch: 
>>> > > Adding new shapes will be cumbersome: we will have to change all 
>>> > > existing visitors to add the new case. 
>>> > > Dangerous for bugs too: when adding new subtypes of Shape, one 
>>> > > might easily forget to override the accept method which will lead 
>>> > > to unwanted behaviour: All visitors would treat instances of the 
>>> > > newly created type like its super type. 
>>> > > 
>>> > So, single dispatch allows you to emulate multiple dispatch, but only 
>>> > awkwardly and in a way that makes any instance of the expression 
>>> > problem (and they are not uncommon at all) a maintenance nightmare. 
>>> > 
>>> > Consider how to make `1 + obj` work just as well as `obj + 1` – i.e. 
>>> > how to make dispatch symmetric for a new type with a pre-existing 
>>> > type. In Python you can use __radd__ methods, but this is clearly a 
>>> > hack that just addresses this one particular instance of the 
>>> > expression problem in a non-general way. What you really need here is 
>>> > precisely multiple dispatch – with it, this is completely trivial to 
>>> > do. In fact, with Julia's promotion and conversion system (which is 
>>> > really just a clever application of multiple dispatch), you don't 
>>> > have to explicitly handle this case, you just provide the appropriate 
>>> > promotion rules and you can solve this entire class of promotion 
>>> > problems all at once in a completely general and extensible way. This 
>>> > is, in fact, how mixed-type arithmetic between built-in types are 
>>> > defined: 
>>> > 
>>> > julia> @less 1 + 2.3 
>>> > +(x::Number, y::Number) = +(promote(x,y)...) 
>>> > 
>>> > If you define your own type, you hook into the same system and it 
>>> > just works. And it's efficient. Despite the fact that really basic 
>>> > mathematical operations like + are generic functions and mixed type 
>>> > addition conceptually goes through many layers of dispatch, it still 
>>> > boils down to the minimal two instructions: 
>>> > 
>>> > julia> @code_llvm 1 + 2.5 
>>> > 
>>> > define double @"julia_+_21457"(i64, double) { 
>>> > top: 
>>> >   %2 = sitofp i64 %0 to double 
>>> >   %3 = fadd double %2, %1 
>>> >   ret double %3 
>>> > } 
>>> > 
>>> > Compare this with the cost of dynamic dispatch through a vtable even 
>>> > in a fast language like C++ – if you had to do addition with two 
>>> > jumps through vtables, it would be a performance disaster. Perhaps 
>>> > you could backport some of the technology from Julia to a single 
>>> > dispatch design. In fact, modern C++ compilers rely heavily on 
>>> > devirtualization, which is essentially a mild form of how Julia's 
>>> > compiler manages this, but I'm really not sure if it would work in 
>>> > the large – there's a strangely nice synergy between dynamic type 
>>> > inference and multiple dispatch. Expressing complex polymorphic 
>>> > behaviors using dispatch is not only convenient, it also gives the 
>>> > compiler a huge amount of type information in a form that it can 
>>> > reason quite effectively about. 
>>> >   
>>> > > 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) 
>>> > > 
>>> > External dispatch does make it non-obvious how to enforce 
>>> > encapsulation. However, lots of languages don't enforce member 
>>> > encapsulation and get by just fine. Python, for example, doesn't have 
>>> > private members, and this doesn't seem to lead to any kind of orgy 
>>> > that I've ever noticed. They have a convention that members starting 
>>> > with _ are private and that works pretty well – if you access one of 
>>> > those and your code breaks in the future, you have only yourself to 
>>> > blame. In Julia, we take this attitude a bit further and consider all 
>>> > fields private unless otherwise indicated in the documentation of a 
>>> > type. So far this hasn't caused trouble. 
>>> Then maybe this fact should be stressed more in the documentation. For 
>>> example, in the manual, nothing implies that fields should be 
>>> considered private at all: 
>>> http://docs.julialang.org/en/latest/manual/types/#composite-types 
>>>
>>> In the recent discussions, I had the feeling that many contributors 
>>> weren't clear on whether fields are considered private or not. 
>>>
>>> Also, to me the project of being able to overload the a.b field access 
>>> syntax [1] goes against the idea that fields are private. In that 
>>> issue, that feature was even considered as a way of implementing an 
>>> abstraction on top of a given structure. That's probably fine as long 
>>> as it's only used by packages interacting with other languages where 
>>> the convention is different, but beyond that it would really blur the 
>>> message about private fields. 
>>>
>>> So basically, I think we should be absolutely clear about whether 
>>> accessing fields from external code is subject to breaking at any point 
>>> or not. (Other than that, I agree with all of your points.) 
>>>
>>>
>>> Regards 
>>>
>>>
>>> 1: https://github.com/JuliaLang/julia/issues/1974 
>>>
>>> > You may find it strange for a language not to have class-based single 
>>> > -dispatch object-orientation because both of the languages you've 
>>> > used happen to have this model. While it's been fairly successful, 
>>> > this model hasn't been the panacea that it was touted to be in the 
>>> > 1990s and early 2000s. There are many programming languages that 
>>> > don't work this way at all and don't miss it. C is still the most 
>>> > popular language and doesn't do this. Almost all the functional 
>>> > languages don't do things this way. Give the multiple dispatch 
>>> > paradigm a try for a while. I think you'll find that it grows on you. 
>>> > Fair warning: after getting used to it, it's hard to go back. 
>>>
>>

Reply via email to