15
$\begingroup$

The documentation says

Import["file.mx"] is equivalent to Get["file.mx"] .

However, I have at least one instance where Get["file.mx"] gives Null, while Import["file.mx"] gives some result (the intended result). I can literally start in a clean Kernel and do one or the other and it is perfectly clear that they are not equivalent. (I even renamed the file to be "file.mx" sort of as a joke, just to proof the documentation completely wrong.)

Now I know this is not the place to put a bug report, but does anyone understand what is going on? (As a side note, there isn't any way to attach a file to a question right?).


This seems to be pretty universal behavior actually. To test it use:

Export["file.mx", {a, b, c}]

and try for yourself. Also adding the format "Package" or "MX" to Get does not affect the result (neither does adding "MX" as the format when exporting).


In more practical terms. I need a function that reliably reads and evaluates data of this type (i.e. matrices or matrices with some function wrapper around them) whether they are stored in an .mx file or in a .txt file (it needs to be able to handle both). Import does not work as this universal function as it will read in the .txt file as a string. I think that ToExpression[Import[#]]& might work universally but I still have to verify this.

$\endgroup$
4
  • $\begingroup$ @Kuba, yes you are right but I have some difficulty with that. I was hoping this might be enough already for someone if it is a well known issue. Otherwise it is slightly difficult to give code that produces the mx file (which we can't read and hence not describe) so that one can create such a file oneself. (I will do so when I have time.) Alternatively, I was hoping that someone would correct me on the no uploading files thing so that I can attach my file.mx. $\endgroup$
    – Kvothe
    Jul 3, 2018 at 16:53
  • 2
    $\begingroup$ @kvothe you can use a free file sharing service to attach your file, but even better would be to include code that generates a MX file so we can all use it. It probably doesn't matter what's in the file; in fact, if it does, that would probably point to the file itself as the origin of the difference, rather than Import and Get. $\endgroup$
    – MarcoB
    Jul 3, 2018 at 17:13
  • $\begingroup$ @GenericAccountName MX is a binary format while Package is a textual format, they aren't equivalent. $\endgroup$ Jul 4, 2018 at 9:57
  • $\begingroup$ @AlexeyPopkov, okay thanks, yes I am not actually familiar with the Package format (the file is I believe in MX format) but since I was asked to try this in the comments I did. $\endgroup$
    – Kvothe
    Jul 4, 2018 at 10:27

1 Answer 1

16
$\begingroup$

You are correct that Import and Get are not quite the same for MX files.

Import is for importing data. Import generally works with various data formats. It returns a representation of the data as a Mathematica expression.

However, MX files don't exactly hold data. They hold definitions associated with symbols. Loading an MX file with Get simply recreates these definitions.

To explain through an example, it is not possible to store a list like {1,2,3} in an MX file. It is necessary to assign this list to a variable, x = {1,2,3}. Then loading the MX file will create the symbol x (if it does not yet exist) and will associate the x = {1,2,3} definition with it. We can also have other types of definitions, e.g. f[x_] := x^2.

At this point you might be saying: "But that's not how Import works with MX files! Export can store plain expressions in an MX file, without associating them with a symbol, and Import can read this data."

Well, that's really just an illusion that Import/Export create through a small trick. The standard way to write MX files is not Export, but DumpSave. When you Export data such as {1,2,3} to MX, first it is associated with a special symbol that Export and Import use internally. Then the definitions of this symbol are saved with DumpSave.

When you use Import to read an MX file, it will check if this symbol's definition has changed after Getting the MX file. If so, it just returns the value of that symbol. If not, it will leave thing as they are.


The special symbol that Export/Import use for MX files is called

System`Private`ConvertersPrivateDumpSymbol

When we do Export["file.mx", {1,2,3}], then the MX file will be equivalent to the following .m file:

System`Private`ConvertersPrivateDumpSymbol := HoldComplete[{1,2,3}]

Now Get["file.mx"] does not return anything, but you can evaluate System`Private`ConvertersPrivateDumpSymbol to check that it has gained a value. Import["file.mx"] will check for this and will return this value. This explains your observations.

$\endgroup$
3
  • 2
    $\begingroup$ One other thing maybe worth mentioning is how truly low-level .mx files are. Get["file.m"] is fundamentally different that Get["file.mx"]. The first allows you to mess with it via tricks like Block and friends. The latter does not. $\endgroup$
    – b3m2a1
    Jul 4, 2018 at 22:37
  • $\begingroup$ @b3m2a1 I always believed that loading an MX directly restores the data structures used internally by Mathematica to store definitions, i.e. there is no evaluation taking place at all. (In reality it is probably a bit more complicated than that though.) $\endgroup$
    – Szabolcs
    Jul 5, 2018 at 8:18
  • $\begingroup$ That's how I view it too. One place it burned me recently was trying to inspect internal definitions by tricking ReadProtected to not get set :) When things are loaded via MX that doesn't work. Of course if they're loaded via an Encode-d .m file it out to still work. $\endgroup$
    – b3m2a1
    Jul 5, 2018 at 8:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.