Experiences with modules

Dear NetLogo team,

Congratulations on the developments with the new module system.

There are still some technical issues (as reported in other posts), but I was able to work around them.

Conceptually, it works for modules defining procedures.
For exporting/importing anything else, there might be problems extending the mechanism.
My plan is to test how I can use the current mechanism for more elaborate encapsulation.

To my surprise, the syntax without quotes even works for relative pathnames – even including .. – and for absolute pathnames on the same drive. For Windows, I could not figure out how to refer to another drive, though.
Another issue might be case-sensitivity. NetLogo is not case-sensitive, but Linux is. This could lead to subtle problems.
Therefore, I would still recommend using module names in quotes.

The syntax for using imported names looks good.
It supports both qualified and unqualified import, as well as changing the name upon import.
All necessary for advanced use.

Thank you for this effort,
Mark

Hi Mark,

Thank you for your comments. The use of .. and absolute paths is not allowed in the specification, so that’s definitely a bug. We are aware of the issue with case-sensitivity, but don’t have a good solution at the moment. For now, it is best to stick to a standard of kebab case filenames, to ensure that everything works as expected on all platforms.

Isaac B.

Hi Isaac,

Thank you for your answer.

I’m not completely sure about the specification. Do you mean the dictionary entry of import?
As far as I could see, it leaves this kind of detail unspecified (after all ../utils/my-tools is a valid NetLogo identifier, though quite unusual).

In my opinion, modules are primarily used for reusing coherent pieces of code.
Then you must be able to specify a relative path at least. Nobody would want to keep all their NetLogo files in one big folder.

May I propose a second form for specifying the module? The import statement could then look like either of these:

and then variations using as within the list of imported names.

As I see it, it is absolutely necessary to support relative paths, and then absolute paths would be a small next step.

Thank you,
Mark

By “specification”, I meant the intended usage that we decided on internally before this release. I don’t think every fine detail is documented yet, but we’ll make sure to fix that for the next iteration of 7.1.

You are right that the purpose of modules is to be able to reuse coherent pieces of code, however it doesn’t seem wise to me to allow these pieces of code to access arbitrary files on the user’s filesystem that are outside the scope of the module. Not allowing import statements to use .. or absolute paths helps sandbox each module to prevent such issues. It also resolves any potential issues with path resolution when sharing or publishing a package, which could get quite hairy if backwards path references were allowed. This doesn’t mean that you should keep all of your NetLogo files in one big folder; the goal is for the module system to behave more like a standard package manager, in that you can just import modules from wherever and NetLogo will resolve the paths/downloads as necessary.

For now, to achieve the functionality in the example you provided, you can place your utils package in the global packages folder (eg. /Library/Application Support/NetLogo/extensions/7.1/packages/utils on Mac or C:/Users/mark/AppData/Roaming/NetLogo/extensions/7.1/packages/utils on Windows) and then import it from any model with import utils.

This also has the advantage of keeping the threshold lower; many users may not understand shell path expansions or absolute paths, so keeping it simple would help those users understand and use the module system.

Isaac B.

There are other levels of reuse than global (packages in the user folder) and local (same folder as the model).

My intention for using modules is creating sub-models is modules. This is not possible yet with the module system as it is, but I hope it can grow into a more general system of reusable model-components.
Then, any level of reuse between global and local would be a logical choice.
And then you would need relative pathnames.

Please, prepare for that kind of use already.

I agree that for many users the variant with quotes would go too far.
Therefore, I proposed it as an alternative. The documentation could even include “advanced” in the description of this variant.
Would you please take this suggestion into consideration?

I understand your desire to create a well-structured system of reusable code, but I’m not seeing how backtracking in paths or using absolute paths would contribute positively to your goal. If you take a NetLogo package and move it somewhere else on your computer, all backtracked paths will break. And if you send someone else a NetLogo package, any absolute paths will break. So it seems to me that designing a system of modules around hardcoded paths like that would not be the best move.

If the concern is that you need your modules to be able to depend on each other, then my instinct is that the internal structure of those modules is incorrect. For example, if you have a module math-utils inside a package utils, and you need math-utils to backtrack in order to use some shared functionality in utils, then it would most likely be better to extract that functionality into a new package called shared-utils and then reference that in both utils and math-utils. Would that solve your problem? If not, we can keep discussing potential ideas, I’m just wary of adding new syntax to support potentially flawed module structures.

Isaac B.

Interestingly, I found a relative path in the Models Library.

Model “Model Visualizer and Plotter Example” refers to the model file as ../../../Sample Models/Biology/Wolf Sheep Predation.nlogox

This is typical for the kind of use I have in mind for relative pathnames when using modules at an intermediate level of reuse. You stay within the folder structure of your project, but go up one or more levels from the current folder.

That’s a good example. I do agree that it makes some sense to allow backtracking only within a package, which would satisfy the concerns I raised earlier. I’m not aware of a package system for any other language that allows this, but if it really would be useful, we can consider keeping it in the NetLogo syntax.

Isaac B.

1 Like

In a sense, Java and Java-based languages do have a system like that, but there all references are relative to the root of the project, so navigation up is always implicit.

Thank you for considering this option.

I think allowing access to modules within a package from anywhere in that package would be a preferable solution to allowing path manipulation. It would be a more robust structure, and it would maintain the current abstraction of imports that would allow modules to exist outside of a filesystem context in the future. As long as we can come up with a good way to denote the root folder of a package, we can definitely add this as a future enhancement!

Isaac B.