Uploaded image for project: 'Request For Comments'
  1. Request For Comments
  2. RFC-34

Standardization of Namespace Aliases

    Details

    • Type: RFC
    • Status: Retired
    • Resolution: Done
    • Component/s: DM, TCT
    • Labels:
    • Location:
      this issue page.

      Description

      We've long had a problem with using namespace aliases inconsistently, and a recent discussion on the review for DM-2305 emphasized the need to actually resolve this rather than just writing different files differently.

      So, as the loudest member of the "no aliases" camp, here's a proposal that still involves some aliases that I could get behind. The tl;dr version is:

      • No file-scope aliases in C++.
      • File-scope aliases in Python like "afw_geom" rather than "afwGeom".
      • Tiny aliases permitted in limited scopes.
      • Use in new files immediately; old files will be migrated when we do the package reorg of DM-2003 (later in S15).

      Here's the detailed proposal:

      C++ Namespace Aliases

      Namespace aliases shall not be used at file or namespace scope in C++. Instead, as many namespace components as needed to disambiguate a name should be used, within the appropriate namespace scope for the current package. More namespace components can be used than are strictly necessary to satisfy the compiler; the goal should be to provide clarity to human readers. The lsst:: namespace component should not be included except in the rare case where the next namespace component is potentially ambiguous (i.e. both ::lsst::foo and ::foo are present), or in a header where it is needed to unconfuse Swig.

      For example, here is how we could refer to various classes from within meas_algorithms:

      namespace lsst { namespace meas { namespace algorithms {
       
      // start with afw because it's necessary, skip lsst::
      afw::geom::Point2D p;  
       
      // no need to say "meas::", because there's only one deblender, but
      // "meas::deblender" would also be fine.
      deblender::BaselineUtils b;  
       
      // using "meas::" is recommended here because there are other packages
      // ending in "base", even though it's clear to the compiler without it
      meas::base::SdssShapeAlgorithm s; 
       
      }}}

      In addition, in contexts where a namespace component conflicts with a frequently-used variable name, additional prefix components should be used (i.e. prefer "afw::image" to "image", because the latter is a very common variable name).

      In function or class scopes, any namespace alias may be used (even much more abbreviated aliases), but these should be limited to cases where the alias is used many times within the function, and usually a typedef or full using declaration is preferred in these contexts.

      Python Module Aliases and Use of import

      Python module aliases used at module scope must be formed from the last N components of their fully-qualified name, joined by underscores instead of periods, with no change in capitalization. For example, lsst.afw.geom.ellipses could be aliased to afw_geom_ellipses, geom_ellipses, or just ellipses, and which of these is chosen is left to the judgement of individual developers. However, the same guidelines discussed for use of C++ namespace components should be applied when determining which namespace components to use in Python aliases: use as many components as needed to avoid reader ambiguity. When only the last component is used, the
      import <package>.<module> as <module>
      form should be used, rather than
      from <package> import <module>,
      to improve readability next to other nearby import statements.

      The
      from <package>.<module> import <names>
      form is also permitted, but the
      from <package>.<module> import *
      form is not, except in cases where names are explicitly being lifted to package or subpackage scope in an __init__.py.

      Motivation

      While this proposal still leaves some room for developer preference, it's much less room than the current situation, and in particular I believe it's enough to be able to reliably search for all possible forms of a namespace with a complex regex, and (perhaps more importantly) search for nearly all possible forms of a namespace with a very simple search.

      Ideally, we'd be able to say
      from lsst import afw.geom
      instead of
      import lsst.afw.geom as afw_geom,
      but alas, we cannot - so I think the latter is the best we can hope for, and much better than the current
      import lsst.afw.geom as afwGeom

      That's because eliminates having the same name capitalized differently in different contexts, and it minimizes having the same name punctuated differently in different contexts, both of which complicate searching - and, to the LSST-uninitiated, code reading - unnecessarily. It also eliminates capital letters from our module aliases, bringing them in line with the PEP 8 guidelines for module and package names (I think a name that's used to refer to a module should look like a module name as much as possible, and our current ones don't).

      Migration

      If this proposal is adopted, I propose we start using it in new files immediately, but leave old files in their current form unless more than ~80% of the file is being rewritten. Old files will be migrated to the new form as part of DM-2003 later in S15, where the namespace themselves will be changing for most packages, and hence we'll need to touch all of the same code anyway. Delaying the migration also leaves us time to synchronize with the HSC fork without complicating those cherry-picks with nomenclature-only changes.

        Attachments

          Issue Links

            Activity

            Hide
            ktl Kian-Tat Lim added a comment -

            Here's my proposed resolution to this issue:

            C++:

            • Jim's rules seem fine; no namespace aliases at file/namespace scope, although the motivation is not completely clear.

            Python:

            • Developers may choose between no alias or "minimum-unambiguous" aliases (as in Jim's example) for imports, with the latter used primarily to shorten names where it is advantageous. Abbreviated aliases will be camelCase in Science Pipelines code that uses camelCase throughout (as is the status quo); they will use underscores in non-Science Pipelines code that is PEP8-ish. I think this will be adequately searchable at the file level, even if finding things at the code line level may take a little more work.
            • np, scipy, plt as described by Robert and John.

            I'll leave this open for the weekend in case someone can't live with that.

            Show
            ktl Kian-Tat Lim added a comment - Here's my proposed resolution to this issue: C++: Jim's rules seem fine; no namespace aliases at file/namespace scope, although the motivation is not completely clear. Python: Developers may choose between no alias or "minimum-unambiguous" aliases (as in Jim's example) for imports, with the latter used primarily to shorten names where it is advantageous. Abbreviated aliases will be camelCase in Science Pipelines code that uses camelCase throughout (as is the status quo); they will use underscores in non-Science Pipelines code that is PEP8-ish. I think this will be adequately searchable at the file level, even if finding things at the code line level may take a little more work. np , scipy , plt as described by Robert and John. I'll leave this open for the weekend in case someone can't live with that.
            Hide
            Parejkoj John Parejko added a comment -

            That sounds like a recipe for confusion: camelCase or no abbreviation sometimes, underscores or no abbreviation other times?

            Show
            Parejkoj John Parejko added a comment - That sounds like a recipe for confusion: camelCase or no abbreviation sometimes, underscores or no abbreviation other times?
            Hide
            ktl Kian-Tat Lim added a comment -

            camelCase in code that otherwise uses camelCase throughout; underscores in code that otherwise uses underscores throughout. Seems consistent to me, since these are local abbreviations for convenience, not global names.

            Show
            ktl Kian-Tat Lim added a comment - camelCase in code that otherwise uses camelCase throughout; underscores in code that otherwise uses underscores throughout. Seems consistent to me, since these are local abbreviations for convenience, not global names.
            Hide
            ktl Kian-Tat Lim added a comment -
            Show
            ktl Kian-Tat Lim added a comment - Adopting this as proposed in https://jira.lsstcorp.org/browse/RFC-34?focusedCommentId=62319&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-62319 Would anyone like to volunteer for an implementation ticket?
            Hide
            swinbank John Swinbank added a comment -

            Per discussion with the proposer on DM-9228, I'm withdrawing this RFC.

            Show
            swinbank John Swinbank added a comment - Per discussion with the proposer on DM-9228 , I'm withdrawing this RFC.

              People

              • Assignee:
                ktl Kian-Tat Lim
                Reporter:
                jbosch Jim Bosch
                Watchers:
                Jim Bosch, John Parejko, John Swinbank, Kian-Tat Lim, Lauren MacArthur, Robert Lupton, Russell Owen, Tim Jenness
              • Votes:
                0 Vote for this issue
                Watchers:
                8 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Planned End:

                  Summary Panel