j3-fortran / fortran_proposals

Proposals for the Fortran Standard Committee
175 stars 14 forks source link

Namespace for modules #1

Open certik opened 4 years ago

certik commented 4 years ago

So you can require module data to be referenced like module.var:

use, namespace :: utils
...
call utils%savetxt()

One issue with just use utils is that it still pollutes your local namespace with savetxt, so that's the reason for use, namespace :: utils.

Other alternatives for syntax: use utils, only (or perhaps use utils, only:). Another alternative is use namespace utils (suggested by Milan Curcic). Or perhaps use, namespace :: utils, to by compatible with the existing syntax like use, intrinsic :: iso_fortran_env.

Initially proposed by Michael Zingale and further discussed at Twitter.

certik commented 4 years ago

The paper is submitted at https://j3-fortran.org/doc/year/19/19-246.txt. I will try to get feedback on it from the committee. CC @zingale.

cmacmackin commented 4 years ago

Agree, this seems like a good feature.

certik commented 4 years ago

So the committee unfortunately did not consider this proposal at the meeting last week. I was hoping to get at least a general "yes" or "no" direction from the committee. But I talked to a few members directly, and I did not hear any "this is a bad idea", or "this should not be done".

Here is my plan:

  1. Write a high quality full proposal for this. This means more use cases, we have to brainstorm any possible issues, and some members of the committee like to structure any new features as "requirements", "specification" and "syntax", so we should incorporate all that.

  2. I will ask on the j3 mailinglist once a more complete proposal is ready to get some feedback

  3. I will ensure that this gets to the committee program for next meeting to be officially considered for the 202y standard.

certik commented 4 years ago

@septcolor that's a valid concern. My plan to overcome this is to use this github repository to get support for proposals. If the Fortran community puts thumbs up for a proposal, or otherwise expresses strong interest, then relatively to other ideas proposed here it will be obvious which proposals are high priority, and which are low priority. And then it will be easier to argue for a particular proposal at the committee.

FortranFan commented 4 years ago

Fyi a new thread at comp.lang.fortran inquiring of a missing feature in current Fortran which can be met by the proposal here: https://groups.google.com/d/msg/comp.lang.fortran/nYdFG0PCTWo/rjjLlAteDgAJ

By the way, I had a similar interest along the lines of this proposal several years ago: https://groups.google.com/forum/#!msg/comp.lang.fortran/sNNnQaoqC9I/JFAEgsbeAPMJ

certik commented 4 years ago

Thanks @FortranFan. This is one of the popular issues in here and I am going to insist for the committee to consider it at the next meeting. However, I welcome any help with improving the current proposal (linked above).

FortranFan commented 4 years ago

@certik wrote:

..However, I welcome any help with improving the current proposal (linked above).

@certik and others interested in this, if you haven't already please take a note of comments online, especially by Ian Harvey at comp.lang.fortran such as this one:

Look at the last 3 questions in that comment: addressing these questions suitably will strengthen the proposal. Some aspects that come to my mind with these questions include:

  1. USE statements can include unnamed operators (+,-*,/, etc.), assignment(=), etc. What is the impact of this proposal on their semantics?
  2. What about named entities which are operators in USE statements e.g., operator(.cross_product.)? Does x .cross_product. y become x foo::operator(.cross_product.) y a la C++?
  3. What about generic interfaces and their extension via USE statements?
  4. Current standard has scoping unit semantics with MODULE subroutines/functions (e.g., for use in SUBMODULEs), INTERFACEs. BLOCK constructs, etc. that can be impacted by USE statements. What happens with them?
certik commented 4 years ago

@FortranFan thanks a lot for pointing these potential issues out. Let's address them.

gronki commented 4 years ago

I think calling DRY good and WET bad is rather arbitrary and not a good argument. More explicit programming can help avoid some mistakes. In python I prefer importing explicitly all names that I use in the code I write. If I feel lazy or only do fast prototyping I import the whole module.

I don't see the discussed feature as necessary but that's because I probably will not use it. But for those who prefer that programming style it might be good to have that option.

Dominik

pon., 18 lis 2019, 18:19 użytkownik septcolor notifications@github.com napisał:

As for why a more explicit namespace control is useful (and so commonly used by other languages), I think there may be at least several reasons:


Reference a module like a global "object"

In object-oriented (OO) programing, we know that it is very convenient to have the ability to refer to components and TBP via the "%" symbol. What we want is close to this ability for a module, such that we can reference an entire module as a global object (like "singleton"). We could mimic its behavior by creating a dummy type that provides aliases to all module variables and contained routines (e.g., via pointers and TBP with NOPASS), but this approach is sometimes rather tedious and may not be straightforward for 3rd-party libraries. I think this kind of extra work becomes unnecessary when a qualifier-based module access is provided at the language level.

About DRY vs WET

The DRY Wiki page mentions WET as an anti-pattern (i.e., not good practice), e.g. "write everything twice" and "we enjoy typing". To import a routine with a long name, I have to type it twice in current Fortran (i.e., once for a USE statement and once for actuall CALL statement). I often find this frustrating when I need to import many routines with long names. Sometimes, it is suggested to use the rename facility of USE (e.g., use foo_mod, only: shortname => long_routine_name), but I feel this approach is often not ideal because of the need to consider yet another name for each imported routine and also because the reader needs to search for their local definition at the top of the current scope.

Matplotlib may be a good "use case" of an explicit qualifier (mpl, plt, etc)

I think a good "real-world" use case may be Python/matplotlib, which commonly use the qualifier "mpl", "plt", and so on. Because Matplotlib contains tons of names/symbols inside, it is clearly not good practice to import all symbols at the same time (via star import). On the other hand, if Python had only Fortran-like import facility, it would have to type every routine names twice, which is very tedious and lengthy in practice.

In addition to the case of Lapack and redundantly named routines (as described in https://j3-fortran.org/doc/year/19/19-246.txt),

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/j3-fortran/fortran_proposals/issues/1?email_source=notifications&email_token=AC4NA3IACAIES5ITFULEN3LQULFB5A5CNFSM4JBFRGNKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEELG26Q#issuecomment-555117946, or unsubscribe https://github.com/notifications/unsubscribe-auth/AC4NA3IAD5NPU5VPGKDAU3TQULFB5ANCNFSM4JBFRGNA .

qolin1 commented 4 years ago

Gets my vote FWIW. I have wanted this for some time, without knowing its name was "namespaces".

certik commented 4 years ago

@qolin1 I just called it "namespaces" for a lack of a better name. We will keep pushing for this at our next committee meeting. I think this is a popular feature.

gronki commented 4 years ago

I would personally deem this low priority too.

pon., 23 gru 2019, 18:00 użytkownik Peter Klausler notifications@github.com napisał:

@qolin1 https://github.com/qolin1 I just called it "namespaces" for a lack of a better name. We will keep pushing for this at our next committee meeting. I think this is a popular feature.

But we need to prioritize. This change is a convenience, not a fix or an enabling feature.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/j3-fortran/fortran_proposals/issues/1?email_source=notifications&email_token=AC4NA3LKUEOVUQP4OQOAL5TQ2DVEJA5CNFSM4JBFRGNKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHRQP5Y#issuecomment-568526839, or unsubscribe https://github.com/notifications/unsubscribe-auth/AC4NA3PAMUL3LSMMTI42HE3Q2DVEJANCNFSM4JBFRGNA .

certik commented 4 years ago

@klausler, @gronki make sure you put thumbs up on issues that you find high priority, and let's collaborate on the top priority issues. I just created #122 for that purpose, let's discuss the list of top priority issues there.

Regarding this issue #1, for me personally this is a huge quality of life improvement, that is a relatively simple feature, and yet it allows to use Fortran modules more like Python. How this stacks up against some other features that we want to push in terms of prioity, that's for a discussion to be had at #122.

jme52 commented 4 years ago
  1. I think this is a good idea. I worked for many years in a code where policy was that module procedures needed to start with the name or the acronym of the module. This would make that code neater.

  2. I like the use, namespace :: utils syntax. I think namespace should be optional and disabled by default for backwards compatibility (sorry if I am stating the obvious).

  3. I agree that % is the fortranic syntax. However, its use may increase the complexity of the rules about scope of identifiers, which will need to be significantly rewritten.

  4. Would it be possible to simultaneously add the possibility of renaming modules (namespaces) as part of the use declaration?

    use, non_intrinsic, namespace :: eh => electronic_history
    implicit none
    call eh%initialise_method
everythingfunctional commented 4 years ago

I like the idea of namespaces, and I like @jme52 syntax example, use, namespace :: sm => some_module, but one thing that should be pointed out is that you would not then be able to do use, namespace :: sm => some_module, only: thing1, thing2. Or at least I don't think you should be able to. Just thought this should be made explicit.

@jme52 , Why do you think using % increases the complexity of rules about scope? Do you have an example of that?

certik commented 4 years ago

@jme52, @everythingfunctional thanks for the feedback, I'll update the proposal.

Yes, use, namespace :: eh => electronic_history should be allowed. And use, namespace :: sm => some_module, only: thing1, thing2 would not be allowed.

As part of this proposal, we also need to ensure we leave the door open if #86 is implemented, so that the syntax could be kept consistent.

jme52 commented 4 years ago

@everythingfunctional, @certik: I don't know why renaming the namespace and specifying some of its names, or even renaming some of its names, should not be allowed, would you mind to elaborate? I cannot see anything wrong in

use, namespace :: eh=>electronic_history, only: init=>default_initialisation_method
call eh%init
everythingfunctional commented 4 years ago

@jme52 , would that imply the following?

use, namespace :: sm => some_module, only: t1 => thing1
call sm%t1
call sm%thing2 ! this would not be allowed because thing2 wasn't brought into scope
call sm%thing1 ! this would not be allowed because thing1 was renamed
certik commented 4 years ago

The general idea that I have about this is the following equivalence between Python / Fortran:

Python Fortran
import A use, namespace :: A
import A as B use, namespace :: B => A
from A import x use A, only: x
from A import x as y use A, only: y => x
from A import * use A

If we allow use, namespace :: sm => some_module, only: t1 => thing1, then it should be a shortcut for:

! Fortran
use, namespace :: sm => some_module
use some_module, only: t1 => thing1

# Python
import some_module as sm
from some_module import thing1 as t1

Which answers @everythingfunctional's question. But I would not allow it, it seems confusing. One can always write the two statements as I did.

everythingfunctional commented 4 years ago

Given that

use, namespace :: sm => some_module, only: t1 => thing1

would be equivalent (if we allowed it) to

use, namespace :: sm => some_module
use some_module, only: t1 => thing1

then

call t1 ! this works
call sm%t1 ! this doesn't work because thing1 still has it's original name through the namespace
call sm%thing1 ! so this works
call sm%thing2 ! and this works
certik commented 4 years ago

@everythingfunctional yes, exactly.

jme52 commented 4 years ago

@certik, @everythingfunctional: that's not what I was trying to propose. To me,

use, namespace :: sm => some_module, only: t1 => thing1

meant "from module some_module, which will be accessed through the sm name, import only thing1, which will be accessed through the name t1. So only sm%t1 would be available (nothing else sm%<...>, and nothing directly from some_module).

Forgetting about the only, do you envision being able to write something like this?

use :: some_module
use, namespace :: sm1 => some_module
use, namespace :: sm2 => some_module

I am not strong on the theory of namespaces, so I don't know if this should be allowed, if it is a good idea, or something to be avoided.

certik commented 4 years ago

To me,

use, namespace :: sm => some_module, only: t1 => thing1

meant "from module some_module, which will be accessed through the sm name, import only thing1, which will be accessed through the name t1. So only sm%t1 would be available (nothing else sm%<...>, and nothing directly from some_module).

I would not do that. Just like you cannot import a derived type and rename or hide some of its parts. Python cannot do this either.

However, I agree that this syntax is confusing and meant a different thing to you than me. That's another reason not to allow it.

Forgetting about the only, do you envision being able to write something like this?

use :: some_module
use, namespace :: sm1 => some_module
use, namespace :: sm2 => some_module

I am not strong on the theory of namespaces, so I don't know if this should be allowed, if it is a good idea, or something to be avoided.

Yes, that should be perfectly fine. An equivalent Python code would be:

from some_module import *
import some_module as sm1
import some_module as sm2
jme52 commented 4 years ago

To me,

use, namespace :: sm => some_module, only: t1 => thing1

meant "from module some_module, which will be accessed through the sm name, import only thing1, which will be accessed through the name t1. So only sm%t1 would be available (nothing else sm%<...>, and nothing directly from some_module).

I would not do that. Just like you cannot import a derived type and rename or hide some of its parts.

The difference is that we can already rename in use statements via rename-list's and only-list's. So if we want to allow for renaming namespaces (which you seem to support), I cannot see a reason why it should not be allowed.

Python cannot do this either.

For any particular reason?

However, I agree that this syntax is confusing and meant a different thing to you than me. That's another reason not to allow it.

I completely understand this meant something different to you, but I think that if any interpretation was included to the standard it would be crystal clear to users with a couple of examples.

To me it's rather the other way: the moment that fortraners who are already used to renaming variables see they can also rename modules they will try to do both at the same time, and they won't understand why they cannot do this.

Forgetting about the only, do you envision being able to write something like this?

use :: some_module
use, namespace :: sm1 => some_module
use, namespace :: sm2 => some_module

I am not strong on the theory of namespaces, so I don't know if this should be allowed, if it is a good idea, or something to be avoided.

Yes, that should be perfectly fine. An equivalent Python code would be:

from some_module import *
import some_module as sm1
import some_module as sm2

To me, multiple namespaces out of a single module sound more complicated: what happens to variables that are save'd inside of the module, does each of the namespaces get a copy of it, or do they share it?

A final comment: I am not sure that something being available or not in Python will be a strong argument for the committee. I think it would be much more helpful to everybody if an example could be presented where this is useful.

certik commented 4 years ago

For any particular reason?

Yes --- I think the reason is that it fundamentally does not make sense. See below.

To me it's rather the other way: the moment that fortraners who are already used to renaming variables see they can also rename modules they will try to do both at the same time, and they won't understand why they cannot do this.

There are two kinds of imports: one imports symbols from a module. We can do that already:

Python Fortran
from A import x use A, only: x
from A import x as y use A, only: y => x
from A import * use A

One can either import all symbols, or just some. And one can also rename symbols on import. I think there is no disagreement here. However, notice that neither Python nor Fortran allows you to import a derived type x and somehow rename its members. That fundamentally does not make sense. You can access the member a as x%a, or if you rename x at import time using y%a. But you cannot rename a to b. If you want to do that, you have to assign it as a variable:

integer :: b
b = x%a

The other kind of import is to import the whole module as a namespace:

Python Fortran
import A use, namespace :: A
import A as B use, namespace :: B => A

One can import it, and optionally rename it. You can view the module A as a derived type. Just like in the previous case it does not make sense to rename members of the derived type, it does not make sense to rename members of the module A if you are accessing them via A%x. If you want to use a different name, you have to do it using a variable, as in the previous case:

type(x_t) :: y
y = A%x

Or you can use associate.

Regarding using Python as an argument --- Python is just an example (but a good one!). Do you know of any language that would allow you to do what you are asking for? Also, do you have any use cases for it?

The use cases for my proposal above are many, e.g., https://github.com/fortran-lang/stdlib/pull/49, https://github.com/fortran-lang/stdlib/issues/99 as well as all the precedents in other languages. I think even you agree with my limited proposal based on your comments above. We are just catching up with other languages and we are not designing something new and untested.

The feature use, namespace :: sm => some_module, only: t1 => thing1 on the other hand does not seem to have precedent in another language and it does not seem to be consistent with Fortran either, per my comment above. As such, that should give us a pause and we should step back and ask if it makes sense what we are designing. If you or others can motivate very well how this make sense and use cases, etc., and can convince the community that we should have it, I am not going to be blocking it. All I am saying is that this seems new and untested and seems inconsistent, so we better be sure we want that.

certik commented 4 years ago

The proposal was submitted as https://j3-fortran.org/doc/year/20/20-108.txt and it was discussed on Wednesday 2/26/2020 at the plenary meeting. I briefly described the feature in 2 minutes and we discussed for about 15 minutes. Here is the feedback from various members of the committee (thus not necessarily consistent):

It seems the main conclusion is to provide better use cases (with derived types, and other things) and to address the above objections in the proposal and resubmit next time.

certik commented 4 years ago

@zingale, @milancurcic I posted the Committee's feedback on this proposal above.

ivan-pi commented 4 years ago

Would wrapping all public subroutines and functions inside a module into a derived type be a simple way of achieving this "namespace" kind of functionality?

module m_foo
    implicit none
    private

    public :: foo

    type :: t_foo
    contains
        procedure :: sqrt => sqrt_
        procedure :: cbrt => cbrt_
    end type

    type(t_foo), protected :: foo = t_foo()

contains

    function sqrt_(this,x) result(res)
        class(t_foo), intent(in) :: this
        real, intent(in) :: x
        real :: res
        res = sqrt(x)
    end function

    function cbrt_(this,x) result(res)
        class(t_foo), intent(in) :: this
        real, intent(in) :: x
        real :: res
        res = x**(1./3.)
    end function

end module

program test_foo
    use m_foo
    implicit none
    print *, foo%sqrt(4.), foo%cbrt(27.) !    2.00000000       3.00000000 
end program

Apart from functions under a generic interface or intrinsic functions, I think it would be doable with some smart preprocessing. There are some problems with this approach, e.g. the module and the type instance which wraps the module functionality must have different names (hence m_foo, t_foo, and foo); the type-bound procedures can in principle reuse intrinsic function names, but the function implementation requires a different name.

The most annoying thing is that you have to duplicate all functions, if you want to have the possibility to call both specific functions or the type-bound procedures:

use m_foo, only: foo, cbrt  ! separate function needed for cbrt

The alternative route using abstract interfaces and procedure pointers doesn't seem to work, as the procedure pointer must be initialized with a variable that reduces to a constant expression.

module m_foo
implicit none
abstract interface
  function sqrt_if(x) result(res)
    real, intent(in) :: x
    real :: res
  end function
end interface

procedure(sqrt_if), pointer :: psqrt => sqrt_ ! allowed

type :: t_foo
  procedure(sqrt_if), pointer, nopass :: sqrt => sqrt_ ! not allowed
end type
type(t_foo), protected :: foo = t_foo()

contains
  function sqrt_(x) result(res)
    real, intent(in) :: x
    real :: res
    res = sqrt(x)
  end function
end module

It is also not possible to use the structure constructor within a module as in type(t_foo), protected :: foo = t_foo(sqrt=sqrt_). It works however if called in the main program as type(t_foo) :: foo; foo = t_foo(sqrt=sqrt_).

certik commented 4 years ago

How would you do it for derived types, global arrays and other entities?

Besides that, your approach would work, but it is so complicated that it's better to not do it at all. For example this proposal allows to use a function both directly or via the module qualifier. In your approach I think you have to use different names.

On Sun, May 3, 2020, at 4:20 PM, Ivan wrote:

Would wrapping all public subroutines and functions inside a module into a derived type be a simple way of achieving this "namespace" kind of functionality?

module m_foo implicit none private

public :: foo

type :: t_foo
contains
    procedure :: sqrt => sqrt_
    procedure :: cbrt => cbrt_
end type

type(t_foo), protected :: foo = t_foo()

contains

function sqrt_(this,x) result(res)
    class(t_foo), intent(in) :: this
    real, intent(in) :: x
    real :: res
    res = sqrt(x)
end function

function cbrt_(this,x) result(res)
    class(t_foo), intent(in) :: this
    real, intent(in) :: x
    real :: res
    res = x**(1./3.)
end function

end module

program test_foo use m_foo implicit none print *, foo%sqrt(4.), foo%cbrt(27.) ! 2.00000000
3.00000000 end program Apart from functions under a generic interface or intrinsic functions, I think it would be doable with some smart preprocessing. There are some problems with this approach, e.g. the module and the type instance which wraps the module functionality must have different names (hence m_foo, t_foo, and foo); the type-bound procedures can in principle reuse intrinsic function names, but the function implementation requires a different name.

The most annoying thing is that you have to duplicate all functions, if you want to have the possibility to call both specific functions or the type-bound procedures:

use m_foo, only: foo, cbrt ! separate function needed for cbrt The alternative route using abstract interfaces and procedure pointers doesn't seem to work, as the procedure pointer must be initialized with a variable that reduces to a constant expression.

module m_foo implicit none abstract interface function sqrt_if(x) result(res) real, intent(in) :: x real :: res end function end interface

procedure(sqrtif), pointer :: psqrt => sqrt ! allowed

type :: t_foo procedure(sqrtif), pointer, nopass :: sqrt => sqrt ! not allowed end type type(t_foo), protected :: foo = t_foo()

contains function sqrt_(x) result(res) real, intent(in) :: x real :: res res = sqrt(x) end function end module It is also not possible to use the structure constructor within a module as in type(t_foo), protected :: foo = t_foo(sqrt=sqrt_). It works however if called in the main program as type(t_foo) :: foo; foo = t_foo(sqrt=sqrt_).

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/j3-fortran/fortran_proposals/issues/1#issuecomment-623191619, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAFAWE2WBFWDPBTX2QR5GDRPXU27ANCNFSM4JBFRGNA.

ivan-pi commented 4 years ago

Essentially, you would need to place the entire contents of the module in the derived type and bind all the procedures. For derived types it does not work, if you mean something like:

use, namespace :: m_foo
type(m_foo%t_foo) :: foo

It is not a good solution, but for modules which only declare functions (e.g. blas or lapack) the functionality is similar (if you can live without being able to import the procedures directly).

I was hoping to show with my example, that similar functionality can already be achieved in Fortran by "misusing" derived types, but as you say the approach is complicated, and it would be nice to develop this into a true language feature which also supported retrieving global entities and derived types.

certik commented 4 years ago

Yes, I agree. Thanks for bringing this idea up.

On Sun, May 3, 2020, at 4:58 PM, Ivan wrote:

Essentially, you would need to place the entire contents of the module in the derived type and bind all the procedures. It is not a good solution, but for modules which only declare functions (e.g. blas or lapack) the functionality is similar (if you can live without being able to import the procedures directly).

I was hoping to show with my example, that similar functionality can already be achieved in Fortran by "misusing" derived types, but as you say the approach is so complicated, it would be better off to develop this into a true language feature.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/j3-fortran/fortran_proposals/issues/1#issuecomment-623197015, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAFAWBMCPSFPBANRU3LGQDRPXZIDANCNFSM4JBFRGNA.

wclodius2 commented 3 years ago

I have written a modified version of your 20-108.txt proposal. While I added some words that I think more clearly expressed the intent of the proposal, and added some use cases, the main change is I have replaced the NAMESPACE attribute for modules with a WITH attribute. I find WITH to be at least as intuitive as NAMESPACE and its brevity more user friendly FWIW I took the WITH attribute from Ada. Is it OK if I upload the revision as revised_namespace_proposal.txt?

certik commented 3 years ago

@wclodius2 yes, please do! Upload it as a new merge request. Let me know if you need any help with git or github. Thanks for bringing fresh ideas into this.

wclodius2 commented 3 years ago

How do I do a merge request?

On Jul 15, 2020, at 6:12 PM, Ondřej Čertík notifications@github.com wrote:

@wclodius2 https://github.com/wclodius2 yes, please do! Upload it as a new merge request. Let me know if you need any help with git or github. Thanks for bringing fresh ideas into this.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/j3-fortran/fortran_proposals/issues/1#issuecomment-659079836, or unsubscribe https://github.com/notifications/unsubscribe-auth/APTQDOWDISOFCNLTHXJGMULR3ZAXXANCNFSM4JBFRGNA.

milancurcic commented 3 years ago

@wclodius2 Follow steps 2 and 3 from here, but adjust the filename/directory for this proposal.

(merge request is same as pull request--the former is git/GitLab jargon, the latter is GitHub jargon :zany_face:)

wclodius2 commented 3 years ago

I thought I did that properly, but I am having the following oddities:

  1. My list of pull requests is showing one request with two files: proposals/default_optional_arguments/revised_proposal.txt, and proposals/namespace_modules/revised_namespace_proposal.txt,
  2. The master directory for proposals/default_optional_arguments/ is not showing revised_proposal.txt though I thought Ondřej approved its pull request. š. The list of pull request is showing not only my request, but an old one from February by Marshallward.

On Jul 17, 2020, at 11:08 AM, Milan Curcic notifications@github.com wrote:

@wclodius2 Follow steps 2 and 3 from here, but adjust the filename/directory for this proposal.

(merge request is same as pull request--the former is git/GitLab jargon, the latter is GitHub jargon 🤪)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

milancurcic commented 3 years ago
  1. My list of pull requests is showing one request with two files: proposals/default_optional_arguments/revised_proposal.txt, and proposals/namespace_modules/revised_namespace_proposal.txt,

@wclodius2 I'm sorry. You did that properly, but my instructions were incorrect in the sense that they don't work if you have 2 concurrent PRs open. I only realize this now. To have 2 or more concurrent PRs, the commits (file additions) you made to your fork need to be made to separate branches. Currently, both proposals you committed to the master branch on your fork, and that's why both proposals now appear in #175.

  1. The master directory for proposals/default_optional_arguments/ is not showing revised_proposal.txt though I thought Ondřej approved its pull request.

This is expected. The PR has not been merged yet, so the file still exists only in your fork. The PR will stay open while we discuss it and edit it in the PR thread, and it will only be merged when it's ready to be uploaded to J3. @certik is this the correct workflow?

  1. The list of pull request is showing not only my request, but an old one from February by Marshallward.

This is also expected. There can be many open PRs at any time.

So, how do you proceed? You need to commit the revised namespace proposal to a new branch on your fork. Perhaps the easiest way to do this is from the GitHub UI. Navigate here and in the upper-right corner click on Add file -> Upload files. Because you don't have write permissions to this repo, GitHub will automatically create a new branch on your fork to which the files will be uploaded. Once done, navigate to https://github.com/j3-fortran/fortran_proposals and near the top there should be a yellow prompt from GitHub asking if you want to open a new PR from the new branch on your fork.

Give it a try, and if there are issues I'd be happy to get on a Zoom call with you to do it together via shared screen.

wclodius2 commented 3 years ago

Don’t I have to first remove /revised_namespace_proposal.txt, from the initial PR?

On Jul 18, 2020, at 11:26 AM, Milan Curcic notifications@github.com wrote:

My list of pull requests is showing one request with two files: proposals/default_optional_arguments/revised_proposal.txt, and proposals/namespace_modules/revised_namespace_proposal.txt, @wclodius2 https://github.com/wclodius2 I'm sorry. You did that properly, but my instructions were incorrect in the sense that they don't work if you have 2 concurrent PRs open. I only realize this now. To have 2 or more concurrent PRs, the commits (file additions) you made to your fork need to be made from separate branches. Currently, both proposals you committed to the master branch on your fork, and that's why both proposals now appear in #175 https://github.com/j3-fortran/fortran_proposals/pull/175.

The master directory for proposals/default_optional_arguments/ is not showing revised_proposal.txt though I thought Ondřej approved its pull request. This is expected. The PR has not been merged yet, so the file still exists only in your fork. The PR will stay open while we discuss it and edit it in the PR thread, and it will only be merged when it's ready to be uploaded to J3. @certik https://github.com/certik is this the correct workflow?

The list of pull request is showing not only my request, but an old one from February by Marshallward. This is also expected. There can be many open PRs at any time.

So, how do you proceed? You need to commit the revised namespace proposal to a new branch on your fork. Perhaps the easiest way to do this is from the GitHub UI. Navigate here https://github.com/j3-fortran/fortran_proposals/tree/master/proposals/namespace_modules and in the upper-right corner click on Add file -> Upload files. Because you don't have write permissions to this repo, GitHub will automatically create a new branch on your fork to which the files will be uploaded. Once done, navigate to https://github.com/j3-fortran/fortran_proposals https://github.com/j3-fortran/fortran_proposals and near the top there should be a yellow prompt from GitHub asking if you want to open a new PR from the new branch on your fork.

Give it a try, and if there are issues I'd be happy to get on a Zoom call with you to do it together via shared screen.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/j3-fortran/fortran_proposals/issues/1#issuecomment-660514603, or unsubscribe https://github.com/notifications/unsubscribe-auth/APTQDOSAJ5KXMKH4XQSZFYLR4HLMNANCNFSM4JBFRGNA.

milancurcic commented 3 years ago

@wclodius2 You don't have to do it first, but yes, revised_namespace_proposal.txt should be removed from the master branch in your fork (wcloudius2/fortran_proposals).

wclodius2 commented 3 years ago

On Jul 18, 2020, at 11:26 AM, Milan Curcic notifications@github.com wrote:

So, how do you proceed? You need to commit the revised namespace proposal to a new branch on your fork. Perhaps the easiest way to do this is from the GitHub UI. Navigate here https://github.com/j3-fortran/fortran_proposals/tree/master/proposals/namespace_modules and in the upper-right corner click on Add file -> Upload files.

Did that and get the error message Uploads are disabled. File uploads require push access to this repository.

I didn’t see anything indicating that GitHub automatically created a branch.

Because you don't have write permissions to this repo, GitHub will automatically create a new branch on your fork to which the files will be uploaded. Once done, navigate to https://github.com/j3-fortran/fortran_proposals https://github.com/j3-fortran/fortran_proposals and near the top there should be a yellow prompt from GitHub asking if you want to open a new PR from the new branch on your fork.

Navigated to https://github.com/j3-fortran/fortran_proposals https://github.com/j3-fortran/fortran_proposals and didn’t see a yellow prompt.

Navigated to https://github.com/wclodius2/fortran_proposals/tree/master/proposals/namespace_modules https://github.com/wclodius2/fortran_proposals/tree/master/proposals/namespace_modules and there is no option to create a new branch and creating a new fork is disabled with the message “Cannot fork because you own this repository and are not a member of any organizations"

milancurcic commented 3 years ago

@wclodius2 Sorry, I thought that would work but it seems like GitHub UI is not as flexible for uploading new files as for editing files in-browser. I went ahead and uploaded your revision in #176 .

wclodius2 commented 3 years ago

Thanks!

On Jul 20, 2020, at 4:40 PM, Milan Curcic notifications@github.com wrote:

@wclodius2 https://github.com/wclodius2 Sorry, I thought that would work but it seems like GitHub UI is not as flexible for uploading new files as for editing files in-browser. I went ahead and uploaded your revision in #176 https://github.com/j3-fortran/fortran_proposals/pull/176 .

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/j3-fortran/fortran_proposals/issues/1#issuecomment-661395704, or unsubscribe https://github.com/notifications/unsubscribe-auth/APTQDOWMMNFFRMDYRGV2CG3R4TBU7ANCNFSM4JBFRGNA.

wclodius2 commented 3 years ago

FWIW I have not seen any further response to this submission. I wonder whether that is because there has been no response or because @milancurcic made the submission and I cannot see responses to submissions by people other than myself? I noticed that some of the participants are labeled Collaborators or Contributors, but I lack such a label and wonder whether it affects what I see?

septcolor commented 3 years ago

Though I'm not sure if this has been discussed already, is it another approach to include the module name itself in the ONLY list (in a way similar to Julia)? For example, assuming that mymod has integer :: foo, baa, this statement

use mymod, only: mymod

allows only a qualified access to foo as

print *, mymod % foo   !! OK
print *, foo   !! error

At the same time, one can also import multiple entities as

use mymod, only: mymod, baa
use mymod, only: m => mymod, b => baa    !! rename

(The corresponding syntax in Julia is like using Printf: Printf and using Printf: Printf, @printf.)


The above approach may help reserve the keyword namespace and with for other purposes. For example, with could be used for importing some components of a derived type into the current scope (to allow unqualified access), e.g.,

with ( myobj : foo, baa, baz )
    print *, foo
    ...
end with

The D language has a similar with statement (https://dlang.org/spec/statement.html#WithStatement).

klausler commented 3 years ago

I like septcolor's suggestion. Would it be transitive -- i.e., if mymod has a use hismod, only: hismod, would mymod%hismod%baz work?

certik commented 3 years ago

I like @septcolor's suggestion also, I haven't thought of that before.

@klausler yes, it would make sense to me for it to be transitive.

septcolor commented 3 years ago

@klauser I think the "transitive" behavior would be very natural and intuitive. For comparison, I've tried this code in Julia, and it seems to behave as expected.

module mymod1
  foo = 100
end

module mymod2
  using ..mymod1: mymod1

  @show mymod1.foo   # OK: 100
  # @show foo        # Error: foo not defined
end

module mymod3
  using ..mymod2: mymod2

  @show mymod2.mymod1.foo   # OK: 100
  # @show mymod1.foo        # Error: mymod1 not defined
end
wclodius2 commented 3 years ago

I am unenthusiastic about overloading the meaning of a keyword like ONLY, but do like the syntactic position of your suggestion. say USE module-name, WITH: module-rename strikes me as relatively intuitive

On Jul 31, 2020, at 1:48 PM, septcolor notifications@github.com wrote:

Though I'm not sure if this has been discussed already, is it another approach to include the module name itself in the ONLY list (in a way similar to Julia)? For example, assuming that mymod has integer :: foo, baa, this statement

use mymod, only: mymod allows only a qualified access to foo as

print , mymod % foo !! OK print , foo !! error At the same time, one can also import multiple entities as

use mymod, only: mymod, baa use mymod, only: m => mymod, b => baa !! rename (The corresponding syntax in Julia is like using Printf: Printf and using Printf: Printf, @printf.)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/j3-fortran/fortran_proposals/issues/1#issuecomment-667321012, or unsubscribe https://github.com/notifications/unsubscribe-auth/APTQDOXGR7MDH4YNKA2NBI3R6MNXZANCNFSM4JBFRGNA.

septcolor commented 3 years ago

(I am sorry if the following has already been discussed in other posts or thread...)

Another popular keyword used for this purpose is import (most notably Python), though this keyword is already used for different purposes (interface blocks) in Fortran. Because import is very common in other languages for importing modules, I guess another approach may be to "reuse" that keyword for importing a module name only (as a namespace), like import mylib at the top of a given scope (which I think corresponds to use, with :: mylib and use, namespace :: mylib).

certik commented 3 years ago

I like the word import the most. But as you said, it might be technically infeasible to use import for both. We need to see.

On Tue, Sep 22, 2020, at 6:09 PM, septcolor wrote:

(I am sorry if the following has already been discussed in other posts or thread...)

Another popular keyword used for this purpose is import (most notably Python), though this keyword is already used for different purposes (interface blocks) in Fortran. Because import is very common in other languages for importing modules, I guess another approach may be to "reuse" that keyword for importing a module name only (as a namespace), like import mylib at a top of a given scope (which I think corresponds to use, with :: mylib and use, namespace :: mylib).

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/j3-fortran/fortran_proposals/issues/1#issuecomment-697046123, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAFAWDYE32IZ2CVYXTGUILSHE4EPANCNFSM4JBFRGNA.