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

Reply via email to