Re: Inconsistent Multiline String Handling in Lua REPL (Direct Input vs. History Recall)

jure bagic <[email protected]> Fri, 31 Jul 2026 09:51:33 +0200
Newsgroups gmane.comp.lang.lua.general
Message-ID <CAOmpovp-WYCbJWTnq-Lytc14hH2b2bTxxSLynwTPm6gp-pmfOw@mail.gmail.com>
--000000000000f961a20657e37532
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Small correction,
the <eof> in error does not necessarily indicate incomplete statement. It
can be an expression, the main point is that once the initial input was not
compiled sucessfully the REPL will now expect a statement (because there
will be no 'return' prepended and your input will be invalid syntax).

-- Jure

On Fri, Jul 31, 2026, 09:11 jure bagic <[email protected]> wrote:

> Lua REPL accepts lines of text, when you press enter the REPL first puts
> "return" before your input and tries to compile it.
>
> For example
> > 69*enter*
> is actually
> > return 69*enter*
>
> Try doing
> > 4, 2, 0*enter*
>
> If such expression compiles, REPL skips trying to compile your input as
> statement.
> Then the compiled function (with prepended 'return' followed by your
> input) is called in order to obtain those values on the stack and finally
> those values are used as arguments to global function 'print' (part of
> basic library).
>
> Otherwise, when compilation with implicit 'return' fails, REPL tries to
> compile your input as statement using a clever hack (in my opinion). As
> long as the input cannot be compiled (syntax error), it checks end of the
> error message to see of it ends with '<eof>' string. This indicates an
> incomplete statement as syntax error will be "near <eof>" (end of file =
=3D=3D
> end of input) because another token was expected before input suddenly
> ended. And then it prompts second time (with '>>') and so on...
>
> So when you do history, you are sending entire expression at once, in
> other words your input can contain multiple newlines because technically
> you only pressed enter once.
>
> -- Jure
>
> On Fri, Jul 31, 2026, 06:46 mathieu stumpf-guntz <[email protected]>
> wrote:
>
>> Hello Martin and Roberto,
>>
>> Thank you very much for all of your insights, that=E2=80=99s very enligh=
tening,
>> though I=E2=80=99ll have to meditate and play a bit more around with it =
before
>> integrating the full lesson here I guess.
>>
>> To respond your question Martin, maybe in a broader fashion than the way
>> you where initially conducting it, what I would expect is a bit less
>> surprise in behaviour while interacting with the interpreter. Though I c=
an
>> get the point that, this or that surprising behavior can be the expected
>> result according to the grammar and the documentation. Even sitting firm=
ly
>> in that scope, having a consistent behavior for the same input whatever =
the
>> input method seems to dwell on an other level of expectation. Consider t=
he
>> following session:
>> Lua 5.3.6 Copyright (C) 1994-2020 Lua.org, PUC-Rio
>> > [[
>> >> test
>> >> ]] =3D=3D "test\n"
>> stdin:3: unexpected symbol near '[[test
>> ]]'
>> > [[
>> test
>> ]] =3D=3D "test\n"
>> true
>> > [[
>> test
>> ]] =3D=3D "test\n"
>> false
>> > [[
>> test
>> ]] =3D=3D "test\n"
>> false
>> > [[
>> test
>> ]] =3D=3D "test\n"
>> true
>>
>> So what happen here:
>> - I typed manually the boolean test and got printed an error informing m=
e
>> of an ill formed construction, fair enough.
>> - Through history facility I select again this ill formed construction
>> and launch interpretation which eventually returns true and prints
>> accordingly.
>> - Then I copy/pasted the whole code snippet in the interpreter, and was
>> informed this time that this is false, the matching value representation
>> being printed.
>> - Then picking this very last entry in history and running it, I still
>> get false printed.
>> - Finally, picking instead in history the earliest item available, we ar=
e
>> back to true being printed.
>>
>> Just reading the session transcript, one could certainly spot what=E2=80=
=99s
>> happening in the directly typed entry thanks the extra `>` hint. But
>> without the previous explanations, one would certainly have a hard time
>> inferring what has actually been done in the subsequent interactions.
>>
>> I hope this clarify what I mean when I say I would expect a more
>> consistent behavior in the REPL.
>>
>> Kind regards,
>> Mathieu
>> On Thursday, July 30, 2026 at 4:42:55=E2=80=AFPM UTC Martin Eden wrote:
>>
>>>
>>> On 2026-07-30 18:05, mathieu stumpf-guntz wrote:
>>> > Not sure what you mean here, but in my previous examples I didn=E2=80=
=99t mean
>>> > I used any magic sequence, the "\n" was actually literal new lines. S=
o
>>> > to make it clear, the test conducted was more like `echo -e
>>> > '[[\ntest\n]]' | lua`,  which ends up (in all configurations I was
>>> > able to try) with
>>> > lua: stdin:3: unexpected symbol near '[[test
>>> > ]]'
>>>
>>> Well that's a different thing! It gives same error for me too.
>>>
>>> So as
>>>
>>>   $ echo -e '123' | lua
>>>   lua: stdin:1: unexpected symbol near '123'
>>>
>>> What result you expect?
>>>
>>> "lua" program in interactive mode silently places expressions
>>> inside "print()". That's neat feature to use it as calculator.
>>>
>>> But neither "[[\ntest\n]]" nor "123" is valid Lua code:
>>> they are expressions, not statements.
>>>
>>> -- Martin
>>>
>>>
>>> --
>> You received this message because you are subscribed to the Google Group=
s
>> "lua-l" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n
>> email to [email protected].
>> To view this discussion visit
>> https://groups.google.com/d/msgid/lua-l/72c88ccc-765c-4d7f-9b19-cf6d5b4a=
509fn%40googlegroups.com
>> <https://groups.google.com/d/msgid/lua-l/72c88ccc-765c-4d7f-9b19-cf6d5b4=
a509fn%40googlegroups.com?utm_medium=3Demail&utm_source=3Dfooter>
>> .
>>
>

--=20
You received this message because you are subscribed to the Google Groups "=
lua-l" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to [email protected].
To view this discussion visit https://groups.google.com/d/msgid/lua-l/CAOmp=
ovp-WYCbJWTnq-Lytc14hH2b2bTxxSLynwTPm6gp-pmfOw%40mail.gmail.com.

--000000000000f961a20657e37532
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"auto">Small correction,<div dir=3D"auto">the &lt;eof&gt; in err=
or does not necessarily indicate incomplete statement. It can be an express=
ion, the main point is that once the initial input was not compiled sucessf=
ully the REPL will now expect a statement (because there will be no &#39;re=
turn&#39; prepended and your input will be invalid syntax).</div><div dir=
=3D"auto"><br></div><div dir=3D"auto">-- Jure</div></div><br><div class=3D"=
gmail_quote gmail_quote_container"><div dir=3D"ltr" class=3D"gmail_attr">On=
 Fri, Jul 31, 2026, 09:11 jure bagic &lt;<a href=3D"mailto:jurebagic99@gmai=
l.com">[email protected]</a>&gt; wrote:<br></div><blockquote class=3D"g=
mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"auto"><div dir=3D"auto">Lua REPL accepts lines of text=
, when you press enter the REPL first puts &quot;return&quot; before your i=
nput and tries to compile it.</div><div dir=3D"auto"><br></div><div dir=3D"=
auto">For example</div><div dir=3D"auto">&gt; 69*enter*</div><div dir=3D"au=
to">is actually</div><div dir=3D"auto">&gt; return 69*enter*</div><div dir=
=3D"auto"><br></div><div dir=3D"auto">Try doing</div><div dir=3D"auto">&gt;=
 4, 2, 0*enter*</div><div dir=3D"auto"><br></div><div dir=3D"auto">If such =
expression compiles, REPL skips trying to compile your input as statement.<=
/div><div dir=3D"auto">Then the compiled function (with prepended &#39;retu=
rn&#39; followed by your input) is called in order to obtain those values o=
n the stack and finally those values are used as arguments to global functi=
on &#39;print&#39; (part of basic library).</div><div dir=3D"auto"><br></di=
v><div dir=3D"auto">Otherwise, when compilation with implicit &#39;return&#=
39; fails, REPL tries to compile your input as statement using a clever hac=
k (in my opinion). As long as the input cannot be compiled (syntax error), =
it checks end of the error message to see of it ends with &#39;&lt;eof&gt;&=
#39; string. This indicates an incomplete statement as syntax error will be=
 &quot;near &lt;eof&gt;&quot; (end of file =3D=3D end of input) because ano=
ther token was expected before input suddenly ended. And then it prompts se=
cond time (with &#39;&gt;&gt;&#39;) and so on...</div><div dir=3D"auto"><br=
></div><div dir=3D"auto">So when you do history, you are sending entire exp=
ression at once, in other words your input can contain multiple newlines be=
cause technically you only pressed enter once.</div><div dir=3D"auto"><br><=
/div><div dir=3D"auto">-- Jure</div></div><br><div class=3D"gmail_quote"><d=
iv dir=3D"ltr" class=3D"gmail_attr">On Fri, Jul 31, 2026, 06:46 mathieu stu=
mpf-guntz &lt;<a href=3D"mailto:[email protected]" target=3D"_blank" re=
l=3D"noreferrer">[email protected]</a>&gt; wrote:<br></div><blockquote =
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid=
;padding-left:1ex"><div>Hello Martin and Roberto,</div><div><br></div><div>=
Thank you very much for all of your insights, that=E2=80=99s very enlighten=
ing, though I=E2=80=99ll have to meditate and play a bit more around with i=
t before integrating the full lesson here I guess.</div><div><br></div><div=
>To respond your question Martin, maybe in a broader fashion than the way y=
ou where initially conducting it, what I would expect is a bit less surpris=
e in behaviour while interacting with the interpreter. Though I can get the=
 point that, this or that surprising behavior can be the expected result ac=
cording to the grammar and the documentation. Even sitting firmly in that s=
cope, having a consistent behavior for the same input whatever the input me=
thod seems to dwell on an other level of expectation. Consider the followin=
g session:<br><div style=3D"background-color:rgb(30,31,34);color:rgb(188,19=
0,196)"><span style=3D"font-family:&quot;JetBrains Mono&quot;,monospace">Lu=
a 5.3.6  Copyright (C) 1994-2020 Lua.org, PUC-Rio<br>&gt; [[<br>&gt;&gt; te=
st<br>&gt;&gt; ]] =3D=3D &quot;test\n&quot;<br>stdin:3: unexpected symbol n=
ear &#39;[[test<br>]]&#39;<br>&gt; [[</span></div><div style=3D"background-=
color:rgb(30,31,34);color:rgb(188,190,196)"><span style=3D"font-family:&quo=
t;JetBrains Mono&quot;,monospace">test</span></div><div style=3D"background=
-color:rgb(30,31,34);color:rgb(188,190,196)"><span style=3D"font-family:&qu=
ot;JetBrains Mono&quot;,monospace">]] =3D=3D &quot;test\n&quot;<br>true<br>=
&gt; [[</span></div><div style=3D"background-color:rgb(30,31,34);color:rgb(=
188,190,196)"><span style=3D"font-family:&quot;JetBrains Mono&quot;,monospa=
ce">test</span></div><div style=3D"background-color:rgb(30,31,34);color:rgb=
(188,190,196)"><span style=3D"font-family:&quot;JetBrains Mono&quot;,monosp=
ace">]] =3D=3D &quot;test\n&quot;<br>false<br>&gt; [[</span></div><div styl=
e=3D"background-color:rgb(30,31,34);color:rgb(188,190,196)"><span style=3D"=
font-family:&quot;JetBrains Mono&quot;,monospace">test</span></div><div sty=
le=3D"background-color:rgb(30,31,34);color:rgb(188,190,196)"><span style=3D=
"font-family:&quot;JetBrains Mono&quot;,monospace">]] =3D=3D &quot;test\n&q=
uot;<br>false<br>&gt; [[</span></div><div style=3D"background-color:rgb(30,=
31,34);color:rgb(188,190,196)"><span style=3D"font-family:&quot;JetBrains M=
ono&quot;,monospace">test</span></div><div style=3D"background-color:rgb(30=
,31,34);color:rgb(188,190,196)"><span style=3D"font-family:&quot;JetBrains =
Mono&quot;,monospace">]] =3D=3D &quot;test\n&quot;<br>true</span></div><br>=
So what happen here:</div><div>- I typed manually the boolean test and got =
printed an error informing=20
me of an ill formed construction, fair enough.</div><div>- Through history =
facility I=20
select again this ill formed construction and launch interpretation=20
which eventually returns true and prints accordingly.<br>- Then I copy/past=
ed the whole code snippet in the interpreter, and was informed this time th=
at this is false, the matching value representation being printed.</div><di=
v>- Then picking this very last entry in history and running it, I still ge=
t false printed.</div><div>- Finally, picking instead in history the earlie=
st item available, we are back to true being printed.</div><div><br></div><=
div></div><div>Just reading the session transcript, one could certainly spo=
t what=E2=80=99s happening in the directly typed entry thanks the extra `&g=
t;` hint. But without the previous explanations, one would certainly have a=
 hard time inferring what has actually been done in the subsequent interact=
ions.</div><div><br></div><div>I hope this clarify what I mean when I say I=
 would expect a more consistent behavior in the REPL.=C2=A0</div><div><br><=
/div><div>Kind regards,<br>Mathieu</div><div class=3D"gmail_quote"><div dir=
=3D"auto" class=3D"gmail_attr">On Thursday, July 30, 2026 at 4:42:55=E2=80=
=AFPM UTC Martin Eden wrote:<br></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0 0 0 0.8ex;border-left:1px solid rgb(204,204,204);padding-lef=
t:1ex">
<br>On 2026-07-30 18:05, mathieu stumpf-guntz wrote:
<br>&gt; Not sure what you mean here, but in my previous examples I didn=E2=
=80=99t mean=20
<br>&gt; I used any magic sequence, the &quot;\n&quot; was actually literal=
 new lines. So=20
<br>&gt; to make it clear, the test conducted was more like `echo -e=20
<br>&gt; &#39;[[\ntest\n]]&#39; | lua`,=C2=A0 which ends up (in all configu=
rations I was=20
<br>&gt; able to try) with
<br>&gt; lua: stdin:3: unexpected symbol near &#39;[[test
<br>&gt; ]]&#39;
<br>
<br>Well that&#39;s a different thing! It gives same error for me too.
<br>
<br>So as
<br>
<br> =C2=A0 $ echo -e &#39;123&#39; | lua
<br> =C2=A0 lua: stdin:1: unexpected symbol near &#39;123&#39;
<br>
<br>What result you expect?
<br>
<br>&quot;lua&quot; program in interactive mode silently places expressions
<br>inside &quot;print()&quot;. That&#39;s neat feature to use it as calcul=
ator.
<br>
<br>But neither &quot;[[\ntest\n]]&quot; nor &quot;123&quot; is valid Lua c=
ode:
<br>they are expressions, not statements.
<br>
<br>-- Martin
<br>
<br>
<br></blockquote></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;lua-l&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:[email protected]" rel=3D"norefe=
rrer noreferrer" target=3D"_blank">[email protected]</a>.<=
br>
To view this discussion visit <a href=3D"https://groups.google.com/d/msgid/=
lua-l/72c88ccc-765c-4d7f-9b19-cf6d5b4a509fn%40googlegroups.com?utm_medium=
=3Demail&amp;utm_source=3Dfooter" rel=3D"noreferrer noreferrer" target=3D"_=
blank">https://groups.google.com/d/msgid/lua-l/72c88ccc-765c-4d7f-9b19-cf6d=
5b4a509fn%40googlegroups.com</a>.<br>
</blockquote></div>
</blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;lua-l&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:[email protected]">lua-l+unsubsc=
[email protected]</a>.<br />
To view this discussion visit <a href=3D"https://groups.google.com/d/msgid/=
lua-l/CAOmpovp-WYCbJWTnq-Lytc14hH2b2bTxxSLynwTPm6gp-pmfOw%40mail.gmail.com?=
utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.com/d/msgid/l=
ua-l/CAOmpovp-WYCbJWTnq-Lytc14hH2b2bTxxSLynwTPm6gp-pmfOw%40mail.gmail.com</=
a>.<br />

--000000000000f961a20657e37532--