How do I avoid this error when using declared variables to create strings?

#1

Here’s a MWE:

``````a = 3
b = 4
``````

(This is from the second tutorial on JuliaBox.com.)

These commands work in isolation (i.e. in a cell by their own, these are IJulia notebooks in Jupyter):

``````"\$(a+b)"
``````
``````"""\$a + \$b"""
``````
``````"""\$(a+b)"""
``````
``````"\$a + \$b"
``````

However the following four commands (each in their own cell of the notebook):

``````"\$a + \$b"
"\$(a+b)"
``````
``````"\$a + \$b"
"""\$(a+b)"""
``````
``````"""\$a + \$b"""
"\$(a+b)"
``````
``````"""\$a + \$b"""
"""\$(a+b)"""
``````

all produce the same error as follows:

``````cannot document the following expression:

"\$(a + b)"

Stacktrace:
[1] error(::String, ::String, ::Vararg{String,N} where N) at ./error.jl:30
``````

Similarly, the following four commands (each in their own cell of the notebook):

``````"\$(a+b)"
"\$a + \$b"
``````
``````"""\$(a+b)"""
"\$a + \$b"
``````
``````"\$(a+b)"
"""\$a + \$b"""
``````
``````"""\$(a+b)"""
"""\$a + \$b"""
``````

all produced the same following error:

``````cannot document the following expression:

"\$(a) + \$(b)"

Stacktrace:
[1] error(::String, ::String, ::Vararg{String,N} where N) at ./error.jl:30
``````

The output of `versioninfo()` is as follows:

``````Julia Version 0.6.2
Commit d386e40c17 (2017-12-13 18:08 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: Intel(R) Xeon(R) CPU E5-2673 v3 @ 2.40GHz
WORD_SIZE: 64
BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell)
LAPACK: libopenblas64_
LIBM: libopenlibm
LLVM: libLLVM-3.9.1 (ORCJIT, haswell)
``````

Anyway at first I thought this might be a bug, but upon further reflection that seems more unlikely than me just doing something wrong (because this is literally the first time I have ever used the language).

So if someone could nudge me back into the right direction of how to use the language’s declared variable string features (the syntax is similar to BASH, which I like) I would greatly appreciate it. Thank you for your time and please enjoy your weekend!

#2

julia thinks that you are trying to document the lower expression.

The way to get around your problem is to assign your multiline string to a variable, e.g.

``````x = """\$(a) + \$(b)"""
"""\$(a+b)"""
``````

then julia will no longer be confused.

Just so that you know, the syntax

``````"""mulitlinestring"""
julia_expression
``````

is reserved for documenting expressions, which is really useful of you write a lot of functions. Here is a rough example:

``````"""
foo(x)

Multiply `x` by two and add three.
"""
function foo(x)
2x + 3
end
``````

Then later on if you want to know what `foo` does you can ask for documentation by pressing `?` at the REPL (works in a notebook too).

``````julia> foo(2)
7

help?> foo
search: floor pointer_from_objref OverflowError RoundFromZero FileMonitor

foo(x)

Multiply x by two and add three.
``````

#3

Dear Jack,

This is really helpful, thank you a lot for this. I really appreciate it.

To clarify, the triple quotes in Julia serve the same purpose as in Python (docstrings)?

How does this explain the problems which occur only using the single quotes?

``````"\$(a+b)"
"\$a + \$b"
``````

and

``````"\$a + \$b"
"\$(a+b)"
``````

also didn’t work, and they have no docstring quotes.

Is this an issue with new lines or white space? I.e. is Julia like C or C++ where every line needs to be ended with a semi-colon?

#4

There’s no such thing as a “docstring quote”—the triple-quotes are just another way of creating a string that lets you do some useful things like put newlines and other quotes inside. Any string can be a docstring if you put it directly before another expression. This means that

``````"\$(a+b)"
"\$a + \$b"
``````

and

``````"""\$(a+b)"""
"""\$a + \$b"""
``````

are both saying the same thing: apply the docstring `"\$(a+b)"` to the string `"\$a + \$b"`—but you can’t document a string, hence the error.

#5

This clarifies a lot of misunderstandings I had, thank you again.

EDIT: I think I have figured it out – the problem is essentially that I am/was lazy and didn’t bother to wrap the expressions with a call to `println()`, so the expressions/statements weren’t separated from each other. I.e. I was using it “too interactively”. Here are the relevant parts of the webpage https://docs.julialang.org/en/release-0.4/manual/noteworthy-differences/ which seem to indicate this to me, although I still need to go back to the tutorial later and see whether this works:

Julia has no line continuation syntax: if, at the end of a line, the input so far is a complete expression, it is considered done; otherwise the input continues. One way to force an expression to continue is to wrap it in parentheses.

In Julia, whitespace is significant, unlike C/C++, so care must be taken when adding/removing whitespace from a Julia program.

Julia does not require the use of semicolons to end statements. The results of expressions are not automatically printed (except at the interactive prompt, i.e. the REPL), and lines of code do not need to end with semicolons. println() or @printf() can be used to print specific output. In the REPL, ; can be used to suppress output. ; also has a different meaning within [ ], something to watch out for. ; can be used to separate expressions on a single line, but are not strictly necessary in many cases, and are more an aid to readability.

/EDIT

original post for historical reasons I suppose? it’s not really that important

So just to be clear, these statements are considered “directly before” each other because there is no end of statement character like a semi-colon or something similar?

Julia discourages the used of semicolons to end statements. The results of statements are not automatically printed (except at the interactive prompt), and lines of code do not need to end with semicolons.

This is confusing because if a semicolon is not needed to end the statement, but a line break is not enough, then what is sufficient to end the statement?

I guess I am somewhat surprised that docstrings can be placed anywhere, not just inside of a function definition. And it is still somewhat unclear to me what I could have done instead to make the code work.