4
$\begingroup$

When trying to import some files into my Mathematica notebook, I wanted to use ToString to specify the file path. Consider the following MWE, where we export some expression to the directory of the notebook, and immediately import it back:

In[1]:= Export[ToString[NotebookDirectory[]]<>"output.txt", 2020];
  import1 = Import[ToString[NotebookDirectory[]]<>"output.txt"]

Out[2]= "2020"

This works as expected. However, consider using Get and its symbolic representation <<:

In[3]:= import2 = Get[ToString[NotebookDirectory[]]<>"output.txt"] 
      << ToString[NotebookDirectory[]]<>"output.txt"

Out[3]= 2020

During evaluation of In[3]:= Get::noopen: Cannot open ToString[NotebookDirectory[]].
During evaluation of In[3]:= StringJoin::string: String expected at position 1 in $Failed<>output.txt.
Out[4]= $Failed <> "output.txt"

SoGet works, but why does << make StringJoin not recognise ToString[NotebookDirectory[]] as a valid StringQ? Am I using incorrect syntax?


Additional question: I also noticed that:

In[5]:= Head/@{import1, import2}

Out[5]= {String, Integer} 

From the documentation, we read that Import "imports data from the source, returning a Wolfram Language representation of it", contrary toGet which also evaluates the expression. Does that mean the Import ed data will always be of the String type, regardless of the type of data I export in the first step?

$\endgroup$
2
  • $\begingroup$ 1. NotebookDirectory already returns a string, so there is no need for ToString. 2. You may want to look at FileNameJoin. 3. The results of Import depends on whether the input can be interpreted and translated to a MMA expression. In most (useful) cases, it will not be a string. See the docs. $\endgroup$
    – MarcoB
    Apr 4, 2020 at 15:20
  • $\begingroup$ Thanks for the answer, I removed ToString; also FileNameJoin is certainly useful. In either case though, the problem with Get vs << persists. I can't understand why the latter does not recognise the file path (everything until "output.txt") as a valid sting. It would be interesting to find out the reason. $\endgroup$
    – dzejkob
    Apr 4, 2020 at 18:17

1 Answer 1

4
$\begingroup$

<< is meant to be used only with a simple name on the right, and it will interpret this name as a string.

<< name means Get["name"] and not Get[name]. << f[] means Get["f[]"] and not Get[f[]].

There are also issues with precedence. << x <> y means StringJoin[ Get["x"], y ]. Try this:

Hold[<< x <> y] // FullForm

(* Hold[StringJoin[Get["x"],y]] *)

Generally, if you want to compute the file name with a function or expression, then use Get[expr]. If you have a literal "filename", then you can use << filename (no quotes needed).

You can, in principle, use the << syntax with expressions. For example, << (f[]), with the parentheses, is interpreted as Get[f[]]. But there is no point in doing this, and many people (including myself) will find it confusing.

$\endgroup$

Your Answer

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

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