Skip to content

Commit a1ecc80

Browse files
ma-laforgeStefanKarpinskiViralBShahvtjnash
authored
Add C/C++ diff: scope, modules, packages. (#37167)
* Add C/C++ diff: scope, modules, packages. * Tweak C/C++ info & wrap lines. * More tweaks to the C++ differences. * Update doc/src/manual/noteworthy-differences.md Co-authored-by: Stefan Karpinski <stefan@karpinski.org> * correction: cwd is not a package repo by default. * Apply suggestions from code review Co-authored-by: Stefan Karpinski <stefan@karpinski.org> Co-authored-by: Viral B. Shah <ViralBShah@users.noreply.github.com> Co-authored-by: Jameson Nash <vtjnash@gmail.com>
1 parent a490197 commit a1ecc80

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

doc/src/manual/noteworthy-differences.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,97 @@ For users coming to Julia from R, these are some noteworthy differences:
351351
it's more general than that since methods are dispatched on every argument type, not only `this`,
352352
using the most-specific-declaration rule).
353353

354+
### Julia &hArr; C/C++: Namespaces
355+
* C/C++ `namespace`s correspond roughly to Julia `module`s.
356+
* There are no private globals or fields in Julia. Everything is publicly accessible
357+
through fully qualified paths (or relative paths, if desired).
358+
* `using MyNamespace::myfun` (C++) corresponds roughly to `import MyModule: myfun` (Julia).
359+
* `using namespace MyNamespace` (C++) corresponds roughly to `using MyModule` (Julia)
360+
* In Julia, only `export`ed symbols are made available to the calling module.
361+
* In C++, only elements found in the included (public) header files are made available.
362+
* Caveat: `import`/`using` keywords (Julia) also *load* modules (see below).
363+
* Caveat: `import`/`using` (Julia) works only at the global scope level (`module`s)
364+
* In C++, `using namespace X` works within arbitrary scopes (ex: function scope).
365+
366+
### Julia &hArr; C/C++: Module loading
367+
* When you think of a C/C++ "**library**", you are likely looking for a Julia "**package**".
368+
* Caveat: C/C++ libraries often house multiple "software modules" whereas Julia
369+
"packages" typically house one.
370+
* Reminder: Julia `module`s are global scopes (not necessarily "software modules").
371+
* **Instead of build/`make` scripts**, Julia uses "Project Environments" (sometimes called
372+
either "Project" or "Environment").
373+
* Build scripts are only needed for more complex applications
374+
(like those needing to compile or download C/C++ executables).
375+
* To develop application or project in Julia, you can initialize its root directory
376+
as a "Project Environment", and house application-specific code/packages there.
377+
This provides good control over project dependencies, and future reproducibility.
378+
* Available packages are added to a "Project Environment" with the `Pkg.add()` function or Pkg REPL mode.
379+
(This does not **load** said package, however).
380+
* The list of available packages (direct dependencies) for a "Project Environment" are
381+
saved in its `Project.toml` file.
382+
* The *full* dependency information for a "Project Environment" is auto-generated & saved
383+
in its `Manifest.toml` file by `Pkg.resolve()`.
384+
* Packages ("software modules") available to the "Project Environment" are loaded with
385+
`import` or `using`.
386+
* In C/C++, you `#include <moduleheader>` to get object/function delarations, and link in
387+
libraries when you build the executable.
388+
* In Julia, calling using/import again just brings the existing module into scope, but does not load it again
389+
(similar to adding the non-standard `#pragma once` to C/C++).
390+
* **Directory-based package repositories** (Julia) can be made available by adding repository
391+
paths to the `Base.LOAD_PATH` array.
392+
* Packages from directory-based repositories do not require the `Pkg.add()` tool prior to
393+
being loaded with `import` or `using`. They are simply available to the project.
394+
* Directory-based package repositories are the **quickest solution** to developping local
395+
libraries of "software modules".
396+
397+
### Julia &hArr; C/C++: Assembling modules
398+
* In C/C++, `.c`/`.cpp` files are compiled & added to a library with build/`make` scripts.
399+
* In Julia, `import [PkgName]`/`using [PkgName]` statements load `[PkgName].jl` located
400+
in a package's `[PkgName]/src/` subdirectory.
401+
* In turn, `[PkgName].jl` typically loads associated source files with calls to
402+
`include "[someotherfile].jl"`.
403+
* `include "./path/to/somefile.jl"` (Julia) is very similar to
404+
`#include "./path/to/somefile.jl"` (C/C++).
405+
* However `include "..."` (Julia) is not used to include header files (not required).
406+
* **Do not use** `include "..."` (Julia) to load code from other "software modules"
407+
(use `import`/`using` instead).
408+
* `include "path/to/some/module.jl"` (Julia) would instantiate multiple versions of the
409+
same code in different modules (creating *distinct* types (etc.) with the *same* names).
410+
* `include "somefile.jl"` is typically used to assemble multiple files *within the same
411+
Julia package* ("software module"). It is therefore relatively straightforward to ensure
412+
file are `include`d only once (No `#ifdef` confusion).
413+
414+
### Julia &hArr; C/C++: Module interface
415+
* C++ exposes interfaces using "public" `.h`/`.hpp` files whereas Julia `module`s `export`
416+
symbols that are intended for their users.
417+
* Often, Julia `module`s simply add functionality by generating new "methods" to existing
418+
functions (ex: `Base.push!`).
419+
* Developers of Julia packages therefore cannot rely on header files for interface
420+
documentation.
421+
* Interfaces for Julia packages are typically described using docstrings, README.md,
422+
static web pages, ...
423+
* Some developers choose not to `export` all symbols required to use their package/module.
424+
* Users might be expected to access these components by qualifying functions/structs/...
425+
with the package/module name (ex: `MyModule.run_this_task(...)`).
426+
427+
### Julia &hArr; C/C++: Quick reference
428+
429+
| Software Concept | Julia | C/C++ |
430+
| :--- | :--- | :--- |
431+
| unnamed scope | `begin` ... `end` | `{` ... `}` |
432+
| function scope | `function x()` ... `end` | `int x() {` ... `}` |
433+
| global scope | `module MyMod` ... `end` | `namespace MyNS {` ... `}` |
434+
| software module | A Julia "package" | `.h`/`.hpp` files<br>+compiled `somelib.a` |
435+
| assembling<br>software modules | `SomePkg.jl`: ...<br>`import("subfile1.jl")`<br>`import("subfile2.jl")`<br>... | `$(AR) *.o` &rArr; `somelib.a` |
436+
| import<br>software module | `import SomePkg` | `#include <somelib>`<br>+link in `somelib.a` |
437+
| module library | `LOAD_PATH[]`, \*Git repository,<br>\*\*custom package registry | more `.h`/`.hpp` files<br>+bigger compiled `somebiglib.a` |
438+
439+
\* The Julia package manager supports registering multiple packages from a single Git repository.<br>
440+
\* This allows users to house a library of related packages in a single repository.<br>
441+
\*\* Julia registries are primarily designed to provide versionning \& distribution of packages.<br>
442+
\*\* Custom package registries can be used to create a type of module library.
443+
444+
354445
## Noteworthy differences from Common Lisp
355446

356447
- Julia uses 1-based indexing for arrays by default, and it can also handle arbitrary [index offsets](@ref man-custom-indices).

0 commit comments

Comments
 (0)