Talk:Pure BF

From Esolang
Jump to navigation Jump to search

An infinite tape can have the type (Sum Integer -> Word8) which can be used as a monad (for +-) and as a comonad (for <>). So you could use (Sum Integer -> IO Word8) to include I/O, or make type Tape = Sum Integer -> Word8; to represent the tape and then make endomorphisms on the IO Kleisli. --Zzo38 19:49, 16 January 2012 (UTC)

Hey, stop being serious!--Tailcalled 22:34, 16 January 2012 (UTC)

I suppose the main advantage of this over standard BF is the ease of implementation in other functional languages. Both with this in mind and to stay true to the functional paradigm, I feel it's better to define constructs in functional terms where possible. The definition "creates a function that threads the parameter into a until the cell under the tape head is 0" uses a while loop - a procedural concept. On the other hand, the equivalent that I've added is functional. — Smjg (talk) 14:22, 17 January 2012 (UTC)

That's not a while loop — "threading...until" suggests recursion with a base case.1 Anyway, this article is an obvious joke, since the semantics of the language are identical to regular BF; indeed, you can frame any language as "pure" in this sense. Perhaps it is accidentally useful as an "implementation guide" to regular BF, though. —ehird 14:40, 17 January 2012 (UTC)
1 Admittedly, it's equivalent to iteration in this case (of course), but this is, after all, all about the wording.

Maybe the World is simply the input and output stream so it is not properly interactive, therefore is not really equivalent to brainfuck. (Brainfuck is interactive and Pure BF is not interactive) --Zzo38 05:41, 19 January 2012 (UTC)

You should technically implement the universe so you can simulate the world while the program is running. --Tailcalled 19:12, 19 January 2012 (UTC)
It depends on what I/O model is being used.
The essence of running a functional program is evaluating an expression. In some languages, like Lazy K, the output is just the result of evaluating a function applied to the input. This isn't interactive.
But it can be made interactive by instead embedding input operations in the output from the main expression. An input operation would read something from the input stream and apply its argument to that input. Take this example in functional pseudocode:
"What's your name? " ++ (readLine (λn → "Hello, " ++ n ++ "!\n"))
This is how LOLA works, and I believe Haskell does something similar. I guess the intention is for Pure BF to be implemented along these lines. — Smjg (talk) 14:27, 19 January 2012 (UTC)
Lazy K is interactive, because it uses lazy IO, and the evaluation order is explicitly specified; actually getting an interactive program to work properly, however, is an exercise in programming in an impure lazy language... —ehird 14:52, 19 January 2012 (UTC)
By "the evaluation order is explicitly specified" do you mean that the language spec makes guarantees about the order in which subexpressions are evaluated, e.g. to prevent input being taken before it's time to use it? That would make sense. So I guess the way to do it in a lazy I/O model is
λinput → "What's your name? " ++ (S lookForEof (λn → "Hello, " ++ n) input)
where lookForEof is a function that recursively takes the tail of its argument until the terminator is reached, then returns I. (Of course, this reads to EOF instead of EOL – but I'm keeping it simple.) — Smjg (talk) 22:01, 19 January 2012 (UTC)
Also, Haskell IO doesn't work that way; it uses monadic IO, which, in its rawest form, basically looks like continuation-passing. You'd write that program as main = putStr "What's your name? " >>= (\() -> hFlush stdout >>= (\() -> getLine >>= (\n -> putStrLn ("hello, " ++ n ++ "!")))). Well, OK, you wouldn't, but you could. —ehird 14:52, 19 January 2012 (UTC)
That's basically what my example is – continuation passing, albeit applied only to input operations. Though you could consider the 'cons' that pieces output characters together as some operation that outputs its first argument and whose second argument is a nullary continuation (this is part of the idea behind LOLA's I/O model too). But I can imagine that monadic I/O is a more powerful system. — Smjg (talk) 22:01, 19 January 2012 (UTC)

I'm confused

"You might say that [a] is a loop, but it isn't. It creates a new function which loops, but that function cannot be executed in Pure BF."  ??? It sure seems to me, from the description, that the interpretation of [a] is a function, which is just composed with the interpretation of any instructions before and after it (which are also functions). If [a] is a function that "cannot be executed in Pure BF" then I don't see how any Pure BF instruction or program can be "executed in Pure BF". Is that the joke, that the result of "running" a Pure BF program is always an unapplied function? (Kind of like a subset of Scheme expressions where the outermost expression must always be lambda?) Chris Pressey (talk) 16:05, 26 November 2012 (UTC)

After reading the description, I'm pretty convinced that indeed is the joke. Implementations are encouraged to apply that function, though. --Koen (talk) 16:14, 26 November 2012 (UTC)
Thing is, if that function is actually applied to a tape/input/output, then this is nothing more than another interpretation of brainfuck (except maybe that it doesn't allow for interactive IO if the composing functions aren't lazily applied). --Koen (talk) 16:17, 26 November 2012 (UTC)
Then allow me to analyze this joke further, in the name of Humour Science.
So you've evaluated a Pure BF program, and now you have a function. What to do with it?
The problem is that the spec doesn't say what you should do with it. Oh, it encourages you to apply it, sure, but encouragement is hardly normative. So it looks like you're free to choose. What are your options?
You could apply it. But then your implementation could just be replaced by a brainfuck interpreter.
You could discard it. But then your impementation could just be replaced by nop.
You could try to output it. But then you need a way to represent it:
  • If you consider brainfuck to be an adequate language to represent such functions in, your implementation could just be replaced by cat.
  • If you consider functions to be extensional objects with no inherent representation, your implementation might as well just be replaced by Hello, world!. (optionally followed by "I has a function")
I can't think of anything else you could reasonably try to do with it. But maybe something will come to me. Chris Pressey (talk) 16:59, 1 December 2012 (UTC)
You could compare it to other functions ;) --ais523 17:21, 1 December 2012 (UTC)
Ways to represent a function:
  • An exhaustive list of (antecedent -> image). If you can enumerate all possible (tape, world) pairs (and if I'm not completely wrong that should be quite easy, if you assume that all inputed tapes have only a finite number of non-zero cells, and every input/output stream is finite (the output stream is kinda useless here, since you can't read from it, but hey we're in a joke right)), then you can start an infinite loop of printing every (tape, world) pair along with its (tape, world) image.
  • A graph. Though you'd have to truncate the number of dimensions, and since everything is discrete you'd be doing basically the same thing as with the association table. But I'm sure that would be fun to represent with maple or some other math software.
I very much like your "brainfuck is an adequate language to represent such functions" suggestion, though. --Koen (talk) 00:23, 2 December 2012 (UTC)
"Use, or use not. There is no mention." -- Yoda Van Orman Quine (-- Chris Pressey (talk) 11:44, 3 December 2012 (UTC))