Skip to main content

programming - Naming convention for symbols exported from package


I know this is a little opinion based, but so is Mathematica style guide and similar topics.


The issue is important so I think this topic will be beneficial for future visitors.



Q: So lowerCaseFunctionName or UpperCaseFunctionName convention for symbols exported from package for users. And why?


I was using lowerCaseCamelCase convention but Szabolcs made some valid points and now I'm not totally convinced. (still using it though)


Let me leave a link to those comments.




  • I'm still using lowerCaseCamelCase because I don't have to worry in future and push fixes which only rename conflicted symbols.


    In my case packages are quite localized but if you build e.g a package with wide applications, it may be that WRI will release something similar.


    Then I'd rather Protect all exported symbols so a user won't be able to do anything wrong, than go back to that again.







https://reference.wolfram.com/language/tutorial/DefiningVariables.html



Answer



Like Leonid, I also prefer capitalized public package symbols. He gave the argument that this is the conventional way to do it and discussed conflicts with builtins (unavoidable) vs conflicts with other packages (avoided through the use of contexts). I would like to add some additional arguments in favour of capitalized package symbols:


The reason why it is recommended to use lower-case symbols for everyday work (i.e working in Global`) is to avoid accidental conflicts with built-in symbols or package symbols. This of course only works if package symbols are all capitalized, just like builtins. Does the same argument about keeping symbols lowercase apply for packages as well, i.e. should packages try to avoid conflicts with the System` context the same way?


There's a big difference between how I write Mathematica code during everyday for or for a package that I might share with others.


Most of the code I write during normal work is written quickly, focuses on getting the task done, and eventually gets thrown away (or replaced). I want to be able to work fast and not worry about name collisions so I use only lowercase symbols.


Package code on the other hand is well thought through and is usually maintained over a long span of time. In this situation having to pay attention to avoiding conflicts with builtin symbols is not a big inconvenience. If a new version of Mathematica comes out and the package conflicts with it, I would just fix that in the next release of the package. But as Leonid said, one might as well put in some thought to at least try to avoid names which might show up in future versions. To sum up: In packages there's much less need for such a safeguard against accidental conflicts with builtins because accidents can be avoided through care. There's also no need to avoid conflicts with other packages because contexts take care of that.


Another difference between everyday code and packages is that packages are used by many people. The package users will typically not be familiar with every single function from the package, and in practice they do treat the package similarly to builtins. It will be beneficial if package symbols do look like builtins so users can just follow the usual lower-case convention and be confident that they won't accidentally conflict with some package symbol they didn't even know about.


Most of what I said here applies to polished packages which might be shared with a large audience. I do not follow the same capitalization guideline for every single .m file I write and use privately, only for packages which were planned as packages from the beginning and which are relatively well thought through.



Comments

Popular posts from this blog

plotting - Filling between two spheres in SphericalPlot3D

Manipulate[ SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, Mesh -> None, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], {n, 0, 1}] I cant' seem to be able to make a filling between two spheres. I've already tried the obvious Filling -> {1 -> {2}} but Mathematica doesn't seem to like that option. Is there any easy way around this or ... Answer There is no built-in filling in SphericalPlot3D . One option is to use ParametricPlot3D to draw the surfaces between the two shells: Manipulate[ Show[SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], ParametricPlot3D[{ r {Sin[t] Cos[1.5 Pi], Sin[t] Sin[1.5 Pi], Cos[t]}, r {Sin[t] Cos[0 Pi], Sin[t] Sin[0 Pi], Cos[t]}}, {r, 1, 2 - n}, {t, 0, Pi}, PlotStyle -> Yellow, Mesh -> {2, 15}]], {n, 0, 1}]

plotting - Plot 4D data with color as 4th dimension

I have a list of 4D data (x position, y position, amplitude, wavelength). I want to plot x, y, and amplitude on a 3D plot and have the color of the points correspond to the wavelength. I have seen many examples using functions to define color but my wavelength cannot be expressed by an analytic function. Is there a simple way to do this? Answer Here a another possible way to visualize 4D data: data = Flatten[Table[{x, y, x^2 + y^2, Sin[x - y]}, {x, -Pi, Pi,Pi/10}, {y,-Pi,Pi, Pi/10}], 1]; You can use the function Point along with VertexColors . Now the points are places using the first three elements and the color is determined by the fourth. In this case I used Hue, but you can use whatever you prefer. Graphics3D[ Point[data[[All, 1 ;; 3]], VertexColors -> Hue /@ data[[All, 4]]], Axes -> True, BoxRatios -> {1, 1, 1/GoldenRatio}]

plotting - Adding a thick curve to a regionplot

Suppose we have the following simple RegionPlot: f[x_] := 1 - x^2 g[x_] := 1 - 0.5 x^2 RegionPlot[{y < f[x], f[x] < y < g[x], y > g[x]}, {x, 0, 2}, {y, 0, 2}] Now I'm trying to change the curve defined by $y=g[x]$ into a thick black curve, while leaving all other boundaries in the plot unchanged. I've tried adding the region $y=g[x]$ and playing with the plotstyle, which didn't work, and I've tried BoundaryStyle, which changed all the boundaries in the plot. Now I'm kinda out of ideas... Any help would be appreciated! Answer With f[x_] := 1 - x^2 g[x_] := 1 - 0.5 x^2 You can use Epilog to add the thick line: RegionPlot[{y < f[x], f[x] < y < g[x], y > g[x]}, {x, 0, 2}, {y, 0, 2}, PlotPoints -> 50, Epilog -> (Plot[g[x], {x, 0, 2}, PlotStyle -> {Black, Thick}][[1]]), PlotStyle -> {Directive[Yellow, Opacity[0.4]], Directive[Pink, Opacity[0.4]],