Yup. The current approach is simply unable to cope with what many people (myself included) have been asking for, which makes it clear that it is only possible in Julia v2.0. This whole thread is yet another case of the inherent issues with the current lookup methods of functions and methods with namespaces. Maybe syntactic sugar is helpful to “get by” while new namespace/lookup design approaches are thought through, but the solution should not be to have a bunch of macros to muck around with other namespaces and manually merge what should be seamless.
Something as radical as Function name conflict: ADL / function merging? is the only way to fundamentally solve this (assuming that it works in Juilia). I think that we made progress there on understanding why the current design is surprising to many people from other languages, and how a using-free design was possible with argument dependent lookup.
But lets say that there is agreement with the core developers that there is a real problem and that lookup rules need to be reexamined (which I am not sure is true we have agreed on yet). Then what is the point of talking about this much pre-v2.0 design?
My answer is that if there is at least some agreement on the direction of method lookup in v2.0 (or that it should be reexamined) then it tells us what sorts of hacky macros are acceptable in the meantime. Put another way, if the end-result is that functions will always be in a global namespace - which counterintuitively ends up helping keep methods in local namespaces - then macro hacks which automatically merge methods are pretty innocuous.
My take is that Julia metaprogramming is powerful enough, that between now and when v2.0 starts being designed, a lot of things can be experimented with (as ideas of how to handle traits have been with Mauro’s packages), so that hopefully some consensus can be reached. (The consensus might just be, as in the case of @enum, that the “hacky macro” approach is just fine )
It is the opposite. From what I can have seen, all people who have actually taken part in creating the julia language are vehemently opposed to anything resembling what is proposed here and in other threads. So to be blunt, this will not happen.
If this is a deal breaker, there are two productive ways forward:
Fork Julia, implement the suggested semantics and win users over by being so much better at dispatch, compilation, taking things seriously etc.
Find another language that already has these semantics implemented and hope for a better experience there.
Or Cassette’s context-specific dispatching could likely make it easy to come up with implementations of these kinds of things.
The best solution is to just not do type-piracy since if you avoid it then you won’t have any problems with method extension. Even if type-piracy didn’t effect other modules, having an overload on basic types that only happens in one module would result in very difficult to understand code anyways (it’s essentially macros to the extreme: all functions can have local contextualizations! Nothing is safe and nothing is marked as being different!), so “don’t do type-piracy” is enforcing an already good programming standard.
I also don’t see how this is solving any real problem other than letting people get away more easily with type-piracy. Method extension is a useful feature because it allows you to define actions on types in a standard way so that generic codes “just work”. @stevengj mentions that you extend Base.+ so that way Base.sum “just works”, but it goes even further: things which have actions like a number can work in DiffEq, Optim.jl, NLsolve.jl, etc. Types and their interfaces are defined via their actions. You cannot write generic code without an assumption of how certain actions work. This just obfuscates these issues to try to make programming look nicer, but results in the loss of one of Julia’s best features: the ease of composition of generic code on user-defined types.
If you’re not extending for the purpose of a useful implementation of an interface, then what for? To not use standardized syntax and apply names/functions in unconventional ways specifically in a single module/script? While I agree that it’s everyone’s right to write bad code, I fail to see how a feature how code obfuscation for mitigation of downstream effects of type-piracy would be a high priority. I would think pretty much everyone working on Julia or using Julia sees other things (caching of native code, debuggers, closure issues, the new optimizer / compilation times, Pkg3, improved linear algebra via BLIS, machine learning / database / data frame/ diffeq / optimization libraries, etc.) as higher priority, which is why this falls on deaf ears.
Lately though I’m really sorely tempted to do some type-piracy, to be able to fix some bugs and limitations in Base just by loading my package (Regex, I’m looking at you!)
This is one of the least helpful comments I have ever seen on discourse, and certainly not the right way to talk to users and people working hard to push the language. It is perfectly reasonable to say “dealing with potential 2.0 design from armchair language designers is low-priority”, but this response is a about the worst thing you could say to me right now. I was seriously consider rethinking your approach to engaging in legitimate discussions and issues with Julia (i.e. it is impossible in julia right now to write practical code with using, and it is possibly fixable).
Luckily I didn’t see this sort of tone when discussing the details with other core developers in Function name conflict: ADL / function merging? when we finally broke through in understanding what the fundamental naming issue is. And for some reason I suspect you have not digested what we discussed there and why Julia is so confusing to people coming from every language except lisp.
With a decoupling of function and method namespaces, type-piracy is a thing of the past. It strengthens the ability to put everything (including operators) in your own namespace for your own types. It is the only practical way to write code which has not using at all, even using Base.
It was not meant to be helpful, it was meant to be truthful. What you want to do with that information is up to you.
I think you should speak for yourself here. I find it very possible to write practical code in julia.
The people I have introduced to julia has given me the impression that they think the multiple dispatch system is very clear and intuitive and have not coded a single line of lisp in their lives. Neither have I for that matter.
Sorry, meant to say “practical code without using”. But please reread that ADL chain, as I think you are applying an extremely dogmatic prior to this all.
This has absolutely nothing to do with julia having multiple-dispatch, it has to do with namespace lookup, which is largely orthogonal (even if it gets trickier).
But I don’t want to rehash that thread again, as it was documented where the confusion lies.
But then what does your code even mean or do? Now your code uses the same syntax as everyone else, but does different things than Base! Now your code adds a + function to your number type but then putting that number into Base.sum, DiffEq, Optim.jl, NLsolve.jl doesn’t work. Now your “generic functions” don’t work on number types you haven’t specifically programmed them for, so they aren’t generic at all. And if you want to just take over every single dispatch to reprogram someone else’s generic code… isn’t this just Cassette’s contextual dispatch?
We all know the things you cannot do if you want to avoid type-piracy. The fact that you cannot do those things doesn’t mean they are a good idea to do it in the first place.
Sometimes code in Base itself commits type-piracy.
I’ve been running into problems with over-broad function deprecations.
My believe is that deprecations should only be for the specific methods that were present (i.e. what methods(function) shows).
If I’ve extended replace or find, perfectly legally, calling them only with my own types, without any type-piracy at all, and then deprecations.jl adds a deprecation that makes all find go to findall, that breaks all my code.
Just to be clear, did you only extend replace or find to make it convenient to call the functions? If so, this is the lack of ADL rearing its ugly head… Not to keep beating a dead horse, but if methods can live with their own types in practice, this stuff is never an issue.
Thanks, I wasn’t aware that was totally decoupled. It’s difficult to model how compilation and multiple dispatch actually works in Julia without reading a lot of code.
Can you expand on this? I would really like to understand what the path is to binary compilation being more common/easy.
This is one of the least helpful comments I have ever seen on discourse, and certainly not the right way to talk to users and people working hard to push the language.
I agree. This kind of comment makes me wonder whether I should give up my attempt to port some GAP code to Julia
You don’t actually need to read a lot of code. code_typed shows you EVERYTHING type inferenced figured out about your code and that’s all what codegen needs. You can see when inference replace a dynamic dispatch with a static one in the output.
There isn’t really much to expand on other than really low level details that whoever implements it has to make design decision on.
I know I try to maintain a distinction in my posts between the #dev and #user categories. The former is much more technical, whereas the latter is much more focused on support. I know many views intermingle the posts from both, but my target audiences are very different.
On that note: a low-hanging fruit that anyone who is perturbed by using can do is to create a tool that converts usings to a discrete set of names. I think this would be well-received.
Indeed it is, as that was a typo. It should have said " it is impossible in julia right now to write practical code withoutusing, and it is possibly fixable)"
The ADL question is how you can avoid using, even using Base and still have functional operators. But no need to rehash that discussion.
Imagine going to a Python forum (even on the eve of Python 1) and saying I love Python, but duck typing is a disaster that makes the language almost unusable. Once we all agree on this fundamental problem, we can work on a solution for Python N+1 that eliminates this flaw while still retaining all of the good things about dynamic typing.
This is roughly the equivalent of going onto a Julia forum and insisting that extensible generic functions (so that a method added in one module can be used in a completely independent module) make it impossible to write practical code.
It’s okay to prefer different language semantics, and it’s okay to question the rationale for these choices! But you have to understand that there will be limited appetite for debate over semantics that have been a core part of the language since its inception (and which are common to many (most? all?) dynamic multiple-dispatch languages).