aboutsummaryrefslogtreecommitdiffhomepage
path: root/notes/module_names.txt
blob: 746ab5f7c226665dd48aa8402fa8b8da43893301 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

Module names
============

We need to resolve name conflicts in some way.
There are a few ways (at a high level) to do side:
1. Enforce unique names by conventions
2. Enforce unique names by a central server or distribution
3. Base names on domain names / URLs
4. Use random names such as UUIDs or public key fingerprints
5. Delegated allocation with a name hierarchy
6. Have multiple namespaces (that can use different ones of the methods 1-5)

Unique naming is needed for several reasons:
1. Unique library filenames (after installation)
2. Dependency resolution (which module is module "x"?)
3. Package management (the package manager needs unique names)

Which are used by other languages and "other things":
1a) Conventions: C, C++ and most older native compiled languages
1b) Central server or distribution: Anything distributed in a GNU/Linux distribution. Node.js/NPM
2. Domain names / URLs: Java, Go
3. Random names: Used in ASN.1's UUID OID subtree
4. Delegated allocation: Used in ASN.1 OIDs
5. Multiple namespaces: Used in ASN.1 (delegated, with a subtree for UUIDs)


Problems with those solutions:
- "Conventions" might not be respected.
- A central server is prone to hoarding/squatting names
  (and centralization isn't very nice by itself)
- Distributions may have internally unique names, but there can still be 
  conflicts between different distros.
- Domain names can expire, change owner, etc. Also:
    - small projects may not register a domain name
      (but this can be solved by using repository URLs instead)
    - but projects may WANT to keep the same identifier
      even after moving to a different host or changing
      owner (e.g. from an individual to an organization).
    - domain names can be long
- Random names are long
- Delegated allocation:
    - UNLESS it allows other types of solutions, it leads to an
      effectively "invite-only" system.
    - Names can get long.
- Multiple namespaces:
    - External tools might forget about less common namespacing systems.

Two-level namespaces with a "group ID"
--------------------------------------

Some module systems use a multi-level namespace system.
For example, a "groupId" and a "package name".
This has some advantages:
- reduces name squatting (only groups/orgs can be name-squatted)
- forks can deviate and add own versions, modify API, etc.
- it makes it clear that a fork is unofficial (but also what it is a fork of)

There is also a major disadvantage:
- forks can no longer work as out-of-the-box drop-in replacements

The "group IDs" can be multiple things:
- usernames
- domain names
- public key fingerprints
- random IDs
- etc.

Two-level namespaces with a "repo ID"
-------------------------------------

This might be a better idea than "group IDs".

The repo ID could be:
* "main" of similar for a central main repository with only
  stable and code-reviewed code.
* "main/std" for things from the language standard itself.
* "staging" for packages that are being reviewed for inclusion
  in the main repo.
* "https://git.example.com/user/repo" for user forks etc.

When there are conflicting names in different repos, it is possible to
check \api_def hashes. If the requested vesions exist in both/all
conflicting-named modules, then the API is compatible and the module
"should" be drop-in replaceable (...this could be a reason to include
black-box tests in the API hashes)

Renaming modules
----------------
Modules may have to be renamed for many reasons:
- name conflict
- legal reasons
- project rename
- etc.

This could be acheived by adding some additional module attributes:

    \oldname OLDNAME <VERSION
        Specifies that the module was renamed at version VERSION (not
        inclusive). Older versions have the name given in OLDNAME

    \oldnameconflict OTHERNEWNAME <OTHERVERSION
        Specifies that another module had the same name as this one, and
        has been renamed, in OTHERVERSION, to OTHERNEWNAME.