10
\$\begingroup\$

Related

The get command, shared by Befunge and ><>, is a command that pops two values x and y and retrieves a value stored at that cell (its counterpart is the put command, which stores a value at a certain cell). The problem is that the 2D surface is the same surface the source code is running off, with uninitialised cells being value 0.

Here is an example of 3 ><> quines, with varying use of the g command:

0:0g:?!;o1+!

This simply iterates over the first line using the get command until it reaches an uninitialised cell (disregard that it's invalid for other reasons).

"r00g>o<

This gets the " from the first cell, avoiding having to calculate the value manually, which is two bytes longer(75*1-).

'rd3*>o<

This avoids the use of the g command altogether and should be valid regardless.


Okay, let me add an edge case to illustrate.

Say there's a challenge to find the product of two positive numbers below 5 without actually using multiplication. Underneath our actual code, we create a box with the appropriate values so that we could simply grab the value at that point on the grid. In Befunge, for example:

&  &  g  .  @
   1  2  3  4  5
   2  4  6  8  10
   3  6  9  12 15
   4  8  12 16 20
   5  10 15 20 25

(Pretend that the numbers are the cell values). Does this count as reading the source code, even when the closest analogy would be declaring a 2D array?

How about the wrapping string literal, a common staple of the 2D language quine? It is also accessing the exact same data that the get command is fetching its data from, which seems like a bit of a double standard to me.

And just the normal string literal? Take the Befunge program "@"#,<, which reuses the @ as both the printed character, and the terminating instruction. Does this count as reading the source code, as it both executes and reads the same character?

\$\endgroup\$
6
  • \$\begingroup\$ I noticed recently, a perfectly valid BF quine that was deleted for source reading, due to using and implementation where ! denotes input after that point. codegolf.stackexchange.com/a/114989/55896 I believe this should be mentioned on this topic \$\endgroup\$ Commented Feb 19, 2018 at 7:17
  • \$\begingroup\$ @DestructibleLemon That one seems completely different to me. The code that is executed and the code that is read are completely separated. The conflict in that answer should be whether the characters after the ! is input (therefore invalid) or data (valid, but not technically BF) \$\endgroup\$
    – Jo King Mod
    Commented Feb 19, 2018 at 7:26
  • \$\begingroup\$ @JoKing "valid, but not technically BF" valid by what standard? The specification? The BF spec is notoriously unclear on edge cases and here on PPCG languages are defined by their implementation anyway, and the weave.rb BF+ interpreter supports ! as a flag. \$\endgroup\$ Commented Feb 19, 2018 at 7:33
  • \$\begingroup\$ If the characters after the ! don't count as input, then the , command no longer reads input, but instead reads from an array. I'm pretty sure this is against BF spec. \$\endgroup\$
    – Jo King Mod
    Commented Feb 19, 2018 at 7:37
  • \$\begingroup\$ The point I was making is that the spec has no standing whatsoever in determining a "valid" BF program. On PPCG the spec might as well not exist. \$\endgroup\$ Commented Feb 19, 2018 at 7:47
  • \$\begingroup\$ Yeah, it's not about the spec, but the implementation, and there does exist an implementation with that behaviour. @EsolangingFruit you should probably undelete that answer \$\endgroup\$ Commented Feb 19, 2018 at 22:03

3 Answers 3

6
\$\begingroup\$

This is no different than self-modifying brainfuck in regards to the rules: it only counts as reading its own source if it does, in fact, read its own source. If the cell being read is outside of the bounding box of the source code, then it's fine. If not, then you're reading the source code.

\$\endgroup\$
8
  • 1
    \$\begingroup\$ If a language has an interpreter (which I'm assuming any self-modifying language does), the interpreter must read the source code in order to run the program. How do you distinguish between actions of the interpreter and those of the program? After all, the purpose of an interpreter is to generate actions for a program, so one could argue that the first step in the execution of a ><> program is to "read the source code, split it on newlines, and store it into a character matrix." Unless you can provide a good way to distinguish between the two cases, I'm afraid I can't agree with this. \$\endgroup\$ Commented Feb 19, 2018 at 7:20
  • \$\begingroup\$ Perhaps this is beyond the scope of this question, but I wouldn't call it "splitting hairs". This does become relevant in some self-modifying languages: for example, Dreaderef's execution model is most naturally described by a ZISC operating on a list of integers whose initial state is given by the program. Any distinction between code and data is made entirely by the programmer, and it is common for Dreaderef programs to do things like having one instruction read and write to the arguments of another (or indeed to themselves). How would your answer handle this? \$\endgroup\$ Commented Feb 19, 2018 at 7:29
  • 2
    \$\begingroup\$ If a character is never executed, can it be read with get? \$\endgroup\$
    – Maya
    Commented Feb 19, 2018 at 15:06
  • \$\begingroup\$ @NieDzejkob That's a very difficult requirement to enforce - I believe it is equivalent to the halting problem. Regardless, you're still loading data into memory via the source code, not via the actions of the program, so I think not. \$\endgroup\$
    – user45941
    Commented Feb 19, 2018 at 19:34
  • \$\begingroup\$ @Mego I would say that this is equivalent to a string literal in a C program. Moreover, this is nowhere near the halting problem. If necessary, one can just add did_execute[IP] = True to the interpreter's main loop. \$\endgroup\$
    – Maya
    Commented Feb 20, 2018 at 14:17
  • 2
    \$\begingroup\$ @NieDzejkob It's close to trivial (in at least some languages) to modify an interpreter and have it indicate whether any given instruction was executed after the fact, but I think Mego is right that determining WITHOUT executing is equivalent to the halting problem, and even determining it after execution but without a modification to the interpreter seems challenging at best. \$\endgroup\$ Commented Feb 20, 2018 at 16:51
  • 3
    \$\begingroup\$ @KamilDrakari Why such arbitrary restriction? In case of the halting problem, you can't just run the program because you won't finish if the answer is "it doesn't halt". Here, running the program is just as good as an algorithm, since it must finish to be a potentially valid submission in the first place. \$\endgroup\$
    – Maya
    Commented Feb 20, 2018 at 17:05
  • \$\begingroup\$ @NieDzejkob The primary difference between a string literal in languages like C and self-modification functionality in e.g. SMBF and Befunge is that those string literals are data that can be manipulated, whereas the latter allows manipulation of code. While the manipulation of data can influence the program's flow, it's in an indirect manner - it's still the same program, but just an alternate control flow. Similarly, reading a string literal's value is not the same thing as reading a program's source, as the literal's value is divorced from the source code - it's just the initial value. \$\endgroup\$
    – user45941
    Commented Feb 27, 2018 at 2:38
2
\$\begingroup\$

If the read value depends on the original source code, then it reads the source code

For example, in a self-modifying language, if the source code has not been modified since the program has started, then executing get would always count as reading your source code.

Another example that counts as reading your source is if get reads a byte which has only been incremented since the start of the program, thus still depending on the original source code.

An example which doesn't count as reading your source code is if get reads a byte which has been replaced with another byte which doesn't depend on the program's source code itself, for example get reading a byte which has been replaced with @, then incremented to A, since the @ hasn't been inferred from the original source code itself via getting.

Examples with ><> programs

01go;
X

This pushes 0 and 1 to the stack (01), then pops those two values and reads (g) the character at that 0-indexed (y, x) position (1, 0) in the (possibly modified) source code (X in this case), prints it (o) and then exits (;). Try it online! Try changing the X to another character, and you'll see that the printed character changes accordingly. Thus, it's evident that g reads part of the original source code.

01g1+01p01go;
@

This gets the character at position (1, 0) of the source as before (01g), increments it (1+), then replaced the character at position (1, 0) of the source with the incremented character (01p), then again gets the character at (1, 0) (01g), and finally prints it and exits (o;). Try it online! As before, if you change the @ to a different character the result will also change. Again, you can see g reads from the original source.

f4*4+01p01go;
I

This pushes 15 (f), multiplies it by 4 (4*) and then adds 4 (4+), resulting in 64, then puts the character with that ASCII code (i.e. @) on (1, 0) (01p), then gets the character at (1, 0) (01g), prints it and exits (o;). Try it online! In this case, if you try changing the I to another character, the output won't change. This is because, regardless of what character you change it to, it will be always replaced with @, therefore making it not count as part of the original source code anymore.

\$\endgroup\$
4
  • \$\begingroup\$ It makes array be read-source? \$\endgroup\$
    – l4m2
    Commented Apr 16, 2018 at 18:12
  • \$\begingroup\$ @l4m2 What? Can you please elaborate? \$\endgroup\$ Commented Apr 16, 2018 at 18:13
  • 2
    \$\begingroup\$ Does't everything a program do depend on the source code, though? \$\endgroup\$ Commented Aug 8, 2018 at 7:11
  • \$\begingroup\$ @EsolangingFruit Technically, reading your own source code is what your programming language always does, regardless of the actual function of the program. However, if the program may try to be aware of its own source code via reading it itself too, then the source code has been read by your program. Whether it actually does so is pretty subjective by itself, so we try to make our consensuses as general and fair to different languages as possible. \$\endgroup\$ Commented Aug 8, 2018 at 8:52
-1
\$\begingroup\$

get is cheating, although the line is blurry

As mentioned in the OP, a prior thread about SMBF resulted in a clear consensus that using the tape values initialized to the source code character values was "cheating" and not a proper quine. It's a fairly strong consensus.

However, a different meta question about Javascript resulted in an equally strong consensus that printing the string representation of a function's source code is valid. The question then becomes, what makes these two different, and which one is get more like?

To put it simply, my interpretation of why the Javascript is valid is just because it accesses a string representation of a function not the program. At least, that's the only distinction I can see between the two. In none of the example programs do I see any indication that the source code of a function is read, but rather that the program's source code is available in full, just like SMBF. If we assume that both prior consensuses are still valid, then get must follow the SMBF precedent.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .