Skip to content

Special name for the current package: @import("self") #6279

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
xackus opened this issue Sep 7, 2020 · 17 comments
Closed

Special name for the current package: @import("self") #6279

xackus opened this issue Sep 7, 2020 · 17 comments
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@xackus
Copy link
Contributor

xackus commented Sep 7, 2020

Proposal: "self" becomes a special package name (like "root" currently is), referring to the current package.

This allows using @import("self") in any file, without specifying a relative path ("../../packagel.zig").

For now, the previous way to refer to the library is the preferred way. The only reason std has itself in its own package map is for this check:

assert(@import("std") == std); // std lib tests require --override-lib-dir

I'd like to keep it referring to std.zig because that is what user made packages will have to do and it's nice to keep the std lib code to match the same thing as an example.

If you like we can do a proposal for a special name to be used for a package to refer to itself. For example we already have @import("root") for referring to the application's root source file, but we could also introduce @import("self") which would refer to its own package. Then for the std lib we would no longer put "std" in the package table; we would rely on the "self" feature, which would be available to all packages. Are you interested in making that proposal?

Originally posted by @andrewrk in #6278 (comment)

@Vexu Vexu added the proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. label Sep 7, 2020
@Vexu Vexu added this to the 0.8.0 milestone Sep 7, 2020
@andrewrk andrewrk added the accepted This proposal is planned. label Sep 7, 2020
@andrewrk
Copy link
Member

andrewrk commented Sep 7, 2020

Accepting now as I think this will be uncontroversial and I don't really see any downsides.

One interesting thing to note is that for applications, @import("root") == @import("self") however that will not be true for libraries.

@ikskuh
Copy link
Contributor

ikskuh commented Sep 7, 2020

May i add a follow-up proposal that could be included here:

As @import is a built-in, it might allow both strings (always user packages) and enum literals (.root, .self, .std) to be imported:

const network = @import("network");
const std = @import(.std);

This would make clear that these packages are magic and provided by the compiler whereas every string is to be given on the command line or in build.zig. It would also free those magic package names

@xackus
Copy link
Contributor Author

xackus commented Sep 8, 2020

@MasterQ32: I don't think this can be done with std because the types used in builtins reside in std.builtin.

@ikskuh
Copy link
Contributor

ikskuh commented Sep 8, 2020

@xackus Builtins (as in functions) can accept any type. In this case: A enum literal, not value from a explicit. This means it should work... But some of the compiler/language devs should think about it as well

@daurnimator
Copy link
Contributor

@xackus / @MasterQ32 even a normal zig function can do that:

fn somefunc(a: anytype) type {
  switch(@typeInfo(@TypeOf(a))) {
    .Pointer => .....,
    .EnumLiteral => ....,
    else => @compileError("invalid type to import"),
  }
}

@andrewrk
Copy link
Member

@MasterQ32 here's a good place for your follow-up proposal: #2206

@luehmann
Copy link
Contributor

luehmann commented May 2, 2022

I think that self might not be the best name for this since it encourages

const self = @import("self");

similarly to how you do

const builtin = @import("builtin");
const root = @import("root");
const std = @import("std");

Reserving self is a bad idea because it will collide with self as a widely used function parameter.

I'd suggest something like package or pkg. Really anything that is not self works.

@andrewrk andrewrk removed the accepted This proposal is planned. label May 2, 2022
@nektro
Copy link
Contributor

nektro commented May 3, 2022

maybe a builtin similar to @This() would be a better approach

@ghost
Copy link

ghost commented May 3, 2022

maybe a builtin similar to @This() would be a better approach

Isn't a top-level @This() already equivalent to importing "self"?

@leecannon
Copy link
Contributor

leecannon commented May 3, 2022

@zzyxyzz this proposal is about a way of importing the root of the current package not the current file.

This does highlight that importing "self" clashes with an already well used idiom of const Self = @This();

@nektro
Copy link
Contributor

nektro commented May 3, 2022

no, it returns the enclosing namespace https://ziglang.org/documentation/master/#This which may or may not be the same thing only if you did it at the top level of the entry point file of the package. this proposal is for anywhere in the package (since they can and usually do span multiple files)

@nektro
Copy link
Contributor

nektro commented May 3, 2022

no one would use the name self or Self for the variable. they'd use the name of their package. generally speaking

@ghost
Copy link

ghost commented May 3, 2022

this proposal is about a way of importing the root of the current package not the current file.

Right. Sorry.

Though I wasn't aware that Zig had the concept of a package root. Isn't it anonymous structs all the way down?

@presentfactory
Copy link

Is this still planned? I would like to use this too because currently the only way to import a package within itself without issues is to use a relative path as mentioned previously and that is undesirable especially when you get into deeper folders.

Another option if the self thing has issues could be to allow letting you specify the package you're in by its name, for example if the Package foo refers to foo.zig then allow foo.zig or any file imported by it to do @import("foo") (as currently this fails and you have to do @import("foo.zig")).

@billzez
Copy link
Contributor

billzez commented Feb 25, 2023

+1

Title should probably be updated to "current module" now.

@deanveloper
Copy link

I think that self might not be the best name

A few alternate names that could be used are mod, module, and module-root. I'm not sure if the accepted label was removed because of the naming issue or if the removal was for different reasons, but I'd love for this functionality to be in Zig as someone who enjoys creating libraries. The special exception so that std can refer to itself with @import("std") was added to address this concern, and it'd be really nice if third-party libraries could do this too 😄

@Lking03x
Copy link

Lking03x commented Oct 23, 2024

Upon encountering the inconvenience, I first thought that @import("root/src_sub_folder/file.zig") would be the way to go however that seems a wrong idea giving the actual semantic of "root" module.

What is needed is the ability to import files relative to the package main source directory as seen in the filesystem hierarchy. As I understand from the discussion "self" will just act like "root" and will rely on the pub / "non pub" of declarations access contains of other files (in other sub directories). I thus think a const self = @import("self") won't solve the problem regardless of the name. Same for a builtin similar to @This().

I propose:

  1. @import("package_name/sub_dir_of_src/file.ext")

    • "package_name" is less likely to collide with an existing module name as it's the actual name of package current get from build.zig.zon.
    • "sub_dir_of_src" is relative to src and follow the filesystem just like relative import does.
    • "ext" maybe "zig" or "zon".
      for example @import("ziggraph/scanner/utils.zig") or @import("ziggraph/ui/screen/test_screen.zig")
      This is similar to how the dart language and others resolve their import.
  2. The approach of using the actual package name may lead to several problem.

    • Some package use special character in their name ("raylib-zig")
    • And it can becomes hard to differentiate which module is the current package
      Instead of "package_name" we may have a generic "package" (which is more explicit than having a symbol like "/"). A module named "package" is also less likely to cause conflict.

    for example @import("package/scanner/utils.zig") or @import("package/ui/screen/test_screen.zig") but also @import("package/main.zig") or @import("package/root.zig").

    Either

    • const package = @import("package") itself won't be legal. In that case @import("package") will only refers to the current package folder, the first folder containing "build.zig" and "build.zig.zon" will walking up the filesystem hierarchy from the caller path. And @import("package/ui/screen/test_screen.zig") becomes @import("package/src/ui/screen/test_screen.zig").
    • or if legal will point to the root file of the current package. In that case @import("package") == @import("package/root.zig") for libraries, assuming "root.zig" is in "package_folder/src". I'm not sure if it's the best way, some packages have ".zig" files in "/lib" sub-directory.

EDIT:
Given that it was intended to access package root via @import old andrew comment and import only take string litteral

EDIT2:
3. "package" may conflit if there is a sub folder with the same name. Instead
- reserve special characters to mark the root source path ("//" or "..."): on unix-like system only their are very few characters sequences that can't be used a directory name.
- have a special builtin for that kind of import
- Change the behavior of import to "if it starts with ./ or ../ then look relative to the directory of the file doing the import" (suggested by andrew #216)

The main point is that we need to be able to import any importable file with a path like syntax relative to the current package directory.

@andrewrk andrewrk closed this as not planned Won't fix, can't repro, duplicate, stale Feb 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests