Open j4james opened 5 years ago
OK, I'll probably respond in more detail when I have more time, but in response to your last point, what would you think if the examples were simply moved to the "historical" section? Maybe a handful of "curated" examples could be retained at the top level. Maybe in the context of a tutorial.
Also:
Yeah, I think moving the example to the historical section is a good idea. For the "curated" examples, I was envisioning ones that are most likely to impress a new user (e.g. stuff like wumpus and mandel), but those aren't necessarily good examples for a tutorial. Which is not to say that a tutorial concept would be a bad idea, but that might require a bit more work than just picking a few of your favourites from the existing examples.
Additional info on point 2: postfix.bf and postfix2.bf are simply copies of rdp.bf and rdp2.bf with b97 headers added. And, like the duplicated quine sources, they aren't listed in the README, whereas the rdp files are. So I'll delete them in #22 like I've deleted the duplicated quine sources. And I think that solves the b97 header file problem, because there are no others that have b97 headers.
(Although, I can see why I tried to rename them: "rdp" is clearly a typo for "rpn" in this instance. These are not recursive descent parsers, these are reverse Polish notation calculators. "postfix" is more meaningful. Should probably rename them still, but, in the README too, and they certainly don't need the b97 headers.)
I'm not sure how I missed those. And I also just noticed that Kimberley's surname is spelt incorrectly - it should be Kimberley Burchett (no 'e' on the end). And if you would like slightly more accurate dates, Dmitry's postfix calculator was posted on 22 Feb 1996, and Kimberley's was posted on 16 Nov 1996.
Okay, I have a lot of catching up to do, but I'll just note one thing that flabbergasts me: neither numer.bf nor digitalr.bf work. It flabbergasts me because the former is one of the original examples, and the latter is by Keymaker who is just really good at esolang if I may say so. Yet, it's true, I tried both, and neither did what I expected them to do. numer tries to divide by zero, and I can't get digitalr to produce any output at all.
numer.bf works as expected if bef
is compiled with unsigned chars (I tried it with gcc option -funsigned-char
.)
numer.bf and prime.bf are both original examples, so their reliance on unsigned chars is curious in light of the DICE compiler almost certainly using signed chars by default, but... well, who knows what the deal was there. At least the behaviour of those two, and rand12.bf, are explainable by the compiler's choice of signedness of char.
digitalr.bf and rand13.bf are a bit more worrisome and are probably worth investigating, as their behaviour doesn't seem to change with unsigned chars.
OK, digitalr.bf works, you just have to end your input with a NUL (ASCII character 0 -- I can enter it by typing Ctrl+@). This should definitely be noted in its description.
numer.bf appears to do a division by zero if the sum is 10 or greater, and it was written before it was explicitly specified that dividing by 0 causes the implementation to ask the operator what the result of dividing by zero should be, so it asks the operator that a lot. (I'm not sure what value, if any, it was originally expecting division by zero to produce.)
Given that numer.bf exists in the historical sources and that digitalr.bf performs the same function, I'd be okay with just deleting it.
I was also tempted to consider digitalr.bf a working example, allowing for the weird end-of-input character, but even then it doesn't actually calculate the digital root correctly. For example, the digital root of 99 is 9 (9+9 = 18, 1+8 = 9), but digitalr says it's zero. The only number that has a digital root of zero is zero itself. I don't know if maybe I'm expecting too much, but I would classify that as buggy.
As for numer.bf, I thought perhaps the original Amiga interpreter didn't fault on a division by zero, and that's why it may have worked in the past. I'm fairly certain the Borland DOS version would have crashed with a Divide error (that was before you started asking for the result of a division by zero).
Then regarding the unsigned char programs, I don't know about prime.bf, but rand12.bf was written by Ben Olmstead, and he had his own interpreter which initially used unsigned memory cells (the issue was brought up at the time, and he fixed it in later versions). And technically rand12.bf still works as a random number generator - it just produces numbers in the range -128 to 127, rather than the 0 to 255 range that is claimed.
As for rand13.bf - that was a modification of his rand12.bf attempt, and I suspect he mistakenly dropped a colon from the end of the second line when trying to golf it (it should have ended ^:p0
). With that fixed, you're still going to get a whole lot of warnings on a modern reference interpreter, but that wouldn't have been an issue at the time.
I've also done a bit more investigation into the bridgeit.bf example, and now that I know what it's trying to do, I'd have to classify it as broken - the warnings are an indication of an actual bug. On the last line, it's trying to write the computer's move onto the board, but it gets the board lookup coordinates the wrong way around - and even then they need to be offset by 48 - so it ends up trying to write somewhere off the playfield.
Even if that were fixed, there is no attempt to put the players move on the board, and no end-game test (the only way to finish is by conceding), so I suspect this may have been a work-in-progress that never got finished. It's rather sad, really, because it looks like it could have been quite a nice little game.
I believe digitalr.bf intends to compute the digital root of a word in the Latin alphabet (like numer.bf does under the right conditions.) A=1, B=2, ... Z=26, so for example the digital root of "cat" is 6 because 3+1+20=24 and 2+4=6. digitalr.bf seems to get this right.
My current plan to "fix" digitalr.bf and prime.bf and rand12.bf is merely to change the description of what they do. This interacts with #23 which I just opened: it will be more strongly justified to describe them in terms of operation with signed cells if we document that signed cells, while technically not specified, are generally expected.
I might rewrite numer.bf instead of deleting it, since apparently I'm its author.
The deal with prime.bf appears to be that it was changed slightly since it was created. Diffing the original version against what's there now I see that 7 characters have changed. The original loops over the integers from 2 to 128. The version that's there now loops over the integers from 2 to 254.
Kalyna would've been using an interpreter compiled with DICE C, which would've been using signed chars for playfield cells. Why it stops at 128 instead of 127 I don't know (the final line is "-128 is not prime"), but 128 is a more reasonable place to stop than 254 for someone using signed char playfield cells.
I suspect I made the changes at some point when I was using an interpreter with unsigned char playfield cells, but I have no recollection of this.
Anyway, reverting prime.bf to its original version seems like the fairest fix.
The deal with numer.bf is, at the end of the loop, the path of execution goes "sideways" over a /
used elsewhere, apparently expecting nothing significant to happen, i.e. for it to act like blank space. If I simply strategically insert some blank spaces so that it doesn't actually execute the /
at the end of the loop, it works perfectly. I'll submit this fix.
I spoke too soon about digitalr.bf. It gets "cat" right but I don't know what it's doing with other, fairly obvious inputs. For example ee
should be 5+5=10 -> 1+0=1, and numer.bf gets this right, but digitalr.bf says this is 7.
Looking at the code for digitalr.bf, it definitely looks to me like it's intended to work with numbers and not letters. Every character that is read has 48 subtracted (i.e. ASCII '0') to get the numeric value. That value is added to a sum, and when the sum is greater than 9 it calculates mod 9 of that value to make it a single digit. It's not an unreasonable algorithm for turning a string of digits into a single digit - it just isn't the actual algorithm for a digital root.
As for prime.bf, it occurred to me that it's not so much that the memory cells need to be unsigned - they just need to have a higher upper bound than 127. So it's possible you made the changes when you were using FBBI, which would have 32-bit memory cells (at least), and thus is easily capable of handling primes up to 254.
Stepping back:
I'm no longer so hot on the idea of simply moving all these examples to a historical section, if there are better ways to deal with the problem. We've had some success "gardening" the example sources so far, so I'm hopeful.
I guess the burning question now is whether bef
should even display warnings by default. If it didn't, that would eliminate the first objection in this issue entirely. But would lack of warnings by default also make learning Befunge-93 frustrating, in a different way? We could instead recontextualize these examples to manage expectations better, noting in the README that many were developed on interpreters that didn't produce warnings and when running them with bef
you should suppress extraneous output with bef -q
.
This seems fair enough - I think the changes you've made have mitigated a lot of the problems. I'm personally not a fan of bef having warnings on by default, but I also know of at least one person who likes warnings, so who knows. Having a note about the issue at the top of the readme is at least something.
I also like the expanded descriptions you've added for some examples - I think more of that would help. Mostly for the programs that take input, where the user just sees a blank screen with no indication of what they are expected to do (what input is permitted, how is it terminated). Some specific examples I found confusing:
The "befunge logo source" programs could also benefit with more detailed explanations. For a long time I totally missed the fact that the source code was intended to spell out the word "BEFUNGE". And the fact that befunge4 and befungex examples are actually reverse quines (whose reversed code does something else) is really impressive, but not at all obvious.
Quoting https://github.com/catseye/Befunge-93/issues/20#issuecomment-426753750 , regarding bridgeit.bf,
Even if that were fixed, there is no attempt to put the players move on the board, and no end-game test (the only way to finish is by conceding), so I suspect this may have been a work-in-progress that never got finished.
It is possible that I never finished it, and testing it now, there are clearly bugs (trying a first move of 32 just causes it to go into an infinite loop, for me), but other things about it have explanations.
It was based on a version of this game I found in some type-in BASIC book. The game is such that the 1st player has a winning strategy (or at least, a can't-lose strategy), and in this implementation the computer is the 1st player; thus there is no need for an end-game test -- the 2nd player is simply forced, at some point, to concede.
I also think (though my recollection on this is less clear) that the board updates were intended only to detect collisions, not display an updated board. (After all, the computer isn't required to maintain a display of the board in a game like this -- you can do it yourself, on paper -- and a lot of old-school computer games did take this approach. Teletype paper isn't free, y'know.) This could explain why the calculations do not place them on the board, and why the human's moves were not recorded (it gives the human no advantage to move to the same place twice.) (Of course it does not explain why the coordinates were swapped. That can only be due to the fact that I am not a very good Befunge programmer.)
All in all, I do remember choosing this game because I thought it would be a good choice because it was simple enough to be programmed in Befunge-93. Unfortunate that it seems I never finished it, yes.
Excuse me @cpressey for irrelevant comment but I've made a pull request and an issue in Funge-98 a while ago, and while you seem to be relatively active in this repo I still have no feedback there. I tried to contact you via email but it didn't work too. I just want to know is it possible to have your feedback that I need to continue my work on my befunge-98 interpreter.
While I'm raising issues about the examples, this is something that really frustrated me when I first started learning Befunge. When you try and run these examples, a significant percentage of them don't actually appear to work. There are four broad categories of problems here:
-i
(or in some cases-q
), these examples can generate a lot of warnings, in many cases overwhelming the actual output, and making them appear to be broken. This includes: beer4.bf, beer10.bf, befunge1.bf, befunge3.bf, befunge4.bf, befungex.bf, bridgeit.bf, palinqn.bf, and rand13.bf.-=
option. This include: postfix.bf, postfix2.bf, quine.bf, quine2.bf, quine3.bf, and revquine.bf.Groups 1 and 2 can possibly be addressed by including an indicator of some sort (e.g. something like a footnote marker) just letting people know that they need to run those examples with the required option enabled. Note that in group 1, most will work with either
-i
or-q
, but bridgeit.bf and palinqn.bf must use the-q
option.Group 3 is more of an issue, but I would have thought you could at least get rid of the broken examples when there is a working replacement. And if you think the broken code is worth keeping for historical interest, perhaps you could move those examples into a separate subdirectory? But worst case, some kind of marker in the readme would be better than nothing.
As for the rest, pi2.bf I'd maybe suggest moving to your FBBI example collection, since the code is still forward compatible with Befunge-98. The others I don't know - maybe just mention something in the readme notes again.
All that said, if I were you I'd probably reconsider whether it's worth keeping many of these examples. I mean do you really need 15 random number generators and 10 different versions of "99 bottles of beer"? The good stuff kind of gets drowned out amongst all the repeats.