isaacg1 / pyth

Pyth, an extremely concise language. Try it here:
https://pyth.herokuapp.com/
MIT License
263 stars 57 forks source link

'F' does not behave as expected after the first command #221

Closed rexroni closed 7 years ago

rexroni commented 7 years ago

This program runs:

FNU5N;
"test"

This program doesn't:

"test"
FNU5N;

Instead, it outputs this error:

test
Traceback (most recent call last):
  File "pyth.py", line 752, in <module>
  File "<string>", line 4, in <module>
  File "/app/macros.py", line 162, in repeat
macros.BadTypeCombinationError: 
Error occured in function: F
Arg 1: [0, 1, 2, 3, 4], type list.
Arg 2: '"', type str.

I see this both in the up-to-date git repo, and in the online interpreter (https://pyth.herokuapp.com/). I am new to pyth, but I don't see anything in the documentation which would indicate this is intentional behavior.

jakobkogler commented 7 years ago

This is not a bug. F simply has a few different functionalities:

  1. The first one is, that will start a loop, if F appears at the beginning of a statement, like in the program FNU5N;
  2. If there is an binary operation in front of it, it will fold the over the operation. For instance *F[2 3 5 7) will fold the list by multiplication, which means it will compute the product 2*3*5*7. This is also often useful if you have a pair of numbers and you want to perform an operation using this number. See Unpacking 2 element tuples with F.
  3. If there is a unary operation in front of F, it will perform this operation a number of times. yFT5 will double 10 5 times, resulting in 320.

Now, why doesn't your example work? Isn't F at the beginning of a statement?

No, it isn't. In Pyth a newline is also an operation (See \n in the Character Reference). This simply prints and returns the result. This can be used for debugging. +\n3\n5 will print 3\n5\n8. See here: code. So since \n is an unary operator, F wants to print N U5 times, which is obviously not possible.

If you want your example to run, simply remove the newline. It gets a little bit harder to read, but it works: "test"FNU5N;

rexroni commented 7 years ago

Ah, thank you for the explanation. I will close the issue.

But isn't it inconsistent to use F[2 3 5 7) and not F[2 3 5 7)? It seems to me that the "main" operator normally comes first (fold) and then the "minor" operator (*)? I know I am lacking the compiler-speak by calling them "main" and "minor" but, that's how it is with "=-K1" for "K-=1", right?