9
\$\begingroup\$

(Inspired by this comment on an old question.)

Background

An error quine (also known as a "Kimian quine") is a program which, when compiled or run, causes the compiler/interpreter/runtime to print an error message that has identical text to the program itself, and nothing else. For the purposes of this challenge, we're defining "error" broadly, to include warnings too.

Task

In this challenge, we're looking for a which is also an error quine. When executed, the program must print its own source code normally (i.e. not as an error/warning message); this must be a proper quine (i.e. some part of the program must encode a different part of the output). Additionally, compiling and executing the program must also cause the program's source code – and nothing else – to be printed as error or warning messages by the implementation. (Note that this means that you will not be able to use compile-time errors, in languages where those prevent the program from executing normally.) So in other words, the program's source code will be printed twice, once via each method.

Clarifications

  • In most cases, it'll be obvious what is and isn't an error/warning message; we aren't distinguishing between the two here. In ambiguous cases, define an error/warning message as any text that's output by the implementation either: 1. as a consequence of something other than executing a command (or whatever the closest equivalent is in the language); or 2. that wasn't part of the input to the command that produced it as output.
  • The error/warning part of the quine doesn't need to be a proper quine (although in most cases it will be by chance, as most error and warning messages contain considerable amounts of fixed text).
  • It's acceptable for the program to output multiple errors/warnings, which form the program's source when concatenated together. It's not acceptable to output errors/warnings that don't appear in the source.
  • Unlike in many challenges, the switches given to the compiler, and the program filename, are likely to be highly relevant in this challenge. Given that the challenge may not be possible otherwise, I'm willing to be flexible here, although if you run the implementation in an unusual way, remember that PPCG rules charge a byte penalty for doing so (equal to the number of additional characters that you'd need to add on the command line over the shortest "normal" way to run a program), and thus you'll need to specify the size of the penalty in your post. (For example, if the interpreter you're using reads the program from a file, and has no particular restrictions on the filename, the shortest normal way to run the program would be from a file with a 1-character filename; thus, if you need a 100-character filename to make your program work, you'd incur a byte penalty of +99.)
  • The compiler/interpreter version you use may well be relevant, so as part of your submission, please state a specific compiler or interpreter on which your program works, and which version is required. (For example, a C submission might state "C (gcc 6.2.0)" in the header.)
  • Note that this task may not be possible in all languages. In the languages where it is, the easiest method will likely be to find an error or warning message for which it's possible to customize some subset of the text (via changing the name of something that gets quoted in the message; filenames are a common choice here, but not the only one). I'll be particularly impressed (and surprised) if someone finds a way to do this using only error and warning messages whose text is fixed.

Victory condition

This is a challenge, so an entry is considered to be better if it has a smaller byte count. As such, once you've got your program working at all, you want to optimize it to bring the number of bytes down as far as possible. (However, don't be discouraged if there's already a shorter entry, especially if it's in a different language; what we're really looking for here is to shorten a particular algorithm or idea behind a program as much as possible, but seeing multiple solutions in different languages or that rely on different principles is always worthwhile.)

\$\endgroup\$
9
  • 2
    \$\begingroup\$ As I said in chat, I think the first bullet point is unclear. In most cases, it'll be obvious what is and isn't an error/warning message just serves as a starting point to discussions and language-lawyering. \$\endgroup\$
    – Dennis
    Commented Jan 5, 2017 at 17:49
  • \$\begingroup\$ @Dennis: I agree in principle that the situation isn't great, but on the other hand can't think of a concrete way to improve it; removing the exception for things that are obviously error messages is likely to lead to some very unintended situations in some languages, which may well cause more damage than it cures; if you think you can improve the question, I have no objection to it being edited (and I don't really think questions on PPCG should have "ownership" anyway, although that's a different issue) \$\endgroup\$
    – user62131
    Commented Jan 5, 2017 at 17:53
  • \$\begingroup\$ As it is, I think the question is unclear and lacking an objective validity criterion. I agree that my proposed change may make things even worse. One possible course of action would be to put the challenge on hold and repost it in the sandbox. \$\endgroup\$
    – Dennis
    Commented Jan 5, 2017 at 18:00
  • 1
    \$\begingroup\$ I've put the challenge on hold for now. I do hope you reconsider reposting it in the sandbox. It's a very interesting idea, and it would be a shame to let it go to waste. \$\endgroup\$
    – Dennis
    Commented Jan 5, 2017 at 18:22
  • 1
    \$\begingroup\$ Sandbox post is here. (I was considering editing that into the question, but that would put the post into the reopen queue, which would be highly counterproductive as it would make it harder to reopen if and when the issues had been resolved.) \$\endgroup\$
    – user62131
    Commented Jan 5, 2017 at 19:14

2 Answers 2

9
\$\begingroup\$

JavaScript (Firefox 50), 153 bytes

Error: "Error: 1.replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x.slice(7)})".replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x.slice(7)})

Explanation

The idea here was to start with the most easily modifiable JS quine I've found yet:

".replace(/.+/,x=>alert(uneval(x)+x))".replace(/.+/,x=>alert(uneval(x)+x))

The throw keyword is a simple way to make it throw its own code as well:

".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})

However, there's a slight problem: Firefox prepends the thrown message with Error:. Fortunately, Error: mycode is actually valid JavaScript! (To learn more about this, visit MDN.)

Error: ".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})Error: ".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})

Oops, this alerts the wrong thing:

".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})Error: ".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})Error: 

Since the quotation mark is no longer at the start of the code, uneval(x)+x won't give us the correct result. The best way to fix this is to add a placeholder in place of the nested string:

Error: "Error: 1.replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x})".replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x})

Uh-oh, now there's an extra Error: in the error message. Let's fix that by slicing the string:

Error: "Error: 1.replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x.slice(7)})".replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x.slice(7)})

And finally, both the output and the error message are identical to the code! I'd add a Stack Snippet, but it doesn't seem to work in a snippet in any browser.

\$\endgroup\$
5
\$\begingroup\$

Python 2, 217 80 51 bytes

The trailing linefeed is required.

s='s=%r;print s%%s;exit(s%%s)';print s%s;exit(s%s)


Try it online

I started with a simple quine:

s='s=%r;print s%%s';print s%s


Then I added raise on the end to throw an IOError.

s='s=%r;print s%%s;raise IOError(s%%s)';print s%s;raise IOError(s%s)


Unfortunately, the traceback was causing problems (I couldn't make it go away completely), and the name of the exception was always printed in front like IOError: <code here>, even if I removed the traceback.

Then I found this helpful SO answer and modified it for my purposes.

Then I found that I can skip creating my own class and can just use sys.exit, making my code much shorter.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I don't think this complies with the definition of error in the challenge spec since it's not as a consequence of something other than executing a command nor it wasn't part of the input to the command that produced it as output. That said, plain exit works just fine here. No need for sys. \$\endgroup\$
    – Dennis
    Commented Jan 5, 2017 at 16:40
  • 1
    \$\begingroup\$ Let us continue this discussion in chat. \$\endgroup\$
    – Dennis
    Commented Jan 5, 2017 at 17:04