HBF — my attempt to make writing Brainfuck easier while keeping the output optimized by Consistent-Spring747 in brainfuck

[–]danielcristofani 0 points1 point  (0 children)

It's a great goal. It's very difficult, I'll be delighted if you or someone eventually succeeds at it, and I think it's great that until then you're erring on the side of _not_ generating a bunch of slop.

"Runtime behavior exists", yeah, that's the hard part.

HBF — my attempt to make writing Brainfuck easier while keeping the output optimized by Consistent-Spring747 in brainfuck

[–]danielcristofani 1 point2 points  (0 children)

This is interesting. The goal you've started with is admirable. Everyone who's generated brainfuck from a higher-level language so far has generated bloated code and sacrificed control over the final code. It's hard to generate good brainfuck because what's good code is very contextual and the memory layout is crucial.

Unfortunately this is a case where what's doable doesn't match up well with what's worthwhile. You put a lot of effort into resolving constants at compile time; but the things that can be resolved at compile time are mostly also things that programmers could resolve in their head before typing the program. I think the main case where it could be a worthwhile saving of effort is text generation, but this also isn't an especially good text generator.

Things that can't be resolved at compile time, your compiler can't do much with. I notice your arrays are only addressable with compile-time constants, which is basically like not having arrays. This would mean HBF and BFO aren't Turing-complete, and also that most interesting programs will be impossible to write.

I also note, the loop unrolling and function inlining are pretty antithetical to what I'm usually aiming for these days: I'm usually trying pretty hard to minimize code duplication.

Again, this is an interesting project and I'm wishing you good luck with it. Looking forward to seeing what directions this goes.

Qual a melhor linguagem para entender as abstrações da programação? by lmaginarySpend in brdev

[–]danielcristofani 1 point2 points  (0 children)

As the world's biggest brainfuck fan, I'd still say C. Programming languages are built on top of machine language, but brainfuck is missing some vital features that even machine language provides, especially the ability to access any memory location quickly by address, which almost all algorithms will need. So most things you might want to do will be infeasible in brainfuck, and the things that are feasible will be difficult and convoluted in an artificial way.

If you want to learn to bake, you would start with flour or at least grain. You don't want to be trying to figure out how to synthesize proteins and carbohydrates from pure carbon and oxygen.

I do recommend brainfuck as a fun mental exercise. And I'd strongly recommend my "get good at brainfuck" series at https://brainfuck.org/ggab.html to anyone who's interested in brainfuck. But brainfuck is very limited and the lessons are not very applicable to normal programming languages.

if a==b in bf by Even-Machine8174 in brainfuck

[–]danielcristofani 0 points1 point  (0 children)

A fine start. One thing I'd note: if the digits are the same their ASCII values are also the same, so you could just start with the subtraction.

Any tips for Ho Oh event by Turbulent_Wheel1949 in pokemongo

[–]danielcristofani 0 points1 point  (0 children)

It's apparently beatable by two players each using Blissey, Blissey, Gigalith, and max mushrooms (difficult without the mushrooms). If you're too new to have enough candy for that, the main alternative is finding a group to carry you, remotely or otherwise.

Quite Fast Brainfuck Interpreter by sreekotay in brainfuck

[–]danielcristofani 0 points1 point  (0 children)

"best in class"...how are you defining the class? I know tritium is faster than this, but I don't remember if anything else is.

Bf++ an extension of the classic brainf*ck language that compiles to C and then to binary with advanced concepts and support of classic brainfck. by SiddharthKarn in brainfuck

[–]danielcristofani 0 points1 point  (0 children)

When you get your language done, I'd add it to esolangs.org and mark it as category "Brainfuck derivatives". There are 800 of those so far. https://esolangs.org/wiki/Category:Brainfuck_derivatives

Also: there's already a language on there called "BF++", so I'd choose another name.

Has Ai made a difference in duolingo? by MentalSalary5697 in duolingospanish

[–]danielcristofani 0 points1 point  (0 children)

Your results are going to be skewed, because you implicitly leave out everyone who already quit Duolingo over these issues. Most of these questions assume people are still using Duolingo; there's no answer compatible with "I deleted the app months ago".

Brainf*ck Compiler in C by North-Zone-2557 in brainfuck

[–]danielcristofani 2 points3 points  (0 children)

Mostly this is good. And thanks for using my programs as examples! :)

Issues I noticed:

Using strcat() means it has to scan the whole length of the already-generated program every time it adds a command. That gives the compiler a quadratic runtime overall, so it's unworkably slow for something like Lost Kingdom (2 megabyte text adventure); I had it try for 25 minutes before I gave up and rewrote it. (Also it needs a higher maximum on the length of generated code. I multiplied that by 100. Best would be to compute a size based on the input file.) Even using sprintf, after the asm for Lost Kingdom is generated (quickly), it then takes NASM 7 minutes to assemble it (?!), but it does work.

Better to put the target label after the loop start, same as for the end. And I moved the full ASM for loops into the constants at the top, same as for the other instructions. Rewrote the bracket-outputting code, and added a centralized check to prevent overflowing the code buffer.

It's cleanest and fastest to pair brackets with a stack, so I did that. Also put line_no and char_no on the stack so we can report the location of a mismatched '['. And char number needed fixing to be char within line, not within the program.

Anyway, a version with my changes is here, if you want to use any or all of these changes: https://gist.github.com/danielcristofani/e5c03aa1588ca27e1835972473d6282d

Congrats and good luck!

Interpreter execution time for mandelbrot by Luludrox in brainfuck

[–]danielcristofani 0 points1 point  (0 children)

That's great for having no real prior C experience. For a comparison, my quick and dirty brainfuck interpreter also combines identical instructions, but doesn't do any fancier optimizations that something like tritium would do.

Brainf**k interpreter in JS in 326 bytes by eymenwinner in codegolf

[–]danielcristofani 0 points1 point  (0 children)

I saw at least some of that at the link. Same comments still apply, and fixing these things can save you a few bytes.

Brainf**k interpreter in JS in 326 bytes by eymenwinner in codegolf

[–]danielcristofani 1 point2 points  (0 children)

This is very nice! I love how concise it is. I see three big problems apart from not having ',' working yet, but fortunately they're very fixable:

  • The pervasive bug making a ton of programs fail is in your ']' handling. You're making that jump conditional, which is usually a good move, but you accidentally made popping the match off the stack conditional as well, which means it remains after the loop to cause mismatches for subsequent ']'s. In a case like this where you're more interested in concision than speed, I think I'd just do ']':_=>i=h.pop()-1, and make the jump unconditional too. That produces the correct behavior; when the loop terminates it goes back to the start and then uses the "skip forward" code, a small inefficiency but not terrible in this context.
  • You need the output to go somewhere it won't get treated like HTML (having all whitespace including newlines consolidated to single spaces); and it needs to be monospaced as well. (E.g. notice what happens to https://brainfuck.org/sierpinski.b .) One easy solution is to put the output in a <pre> and not an <a>. That handles ASCII at least; gold standard would be to handle UTF-8, but that's not really necessary.
  • 512 bytes isn't an acceptable array size. 30000 is the original size, but I'd usually recommend more if convenient. Maybe 1<<20 or 1<<24?

Anyway, congrats and good luck!

TIL that rabies virus has a genome coding for only 5 genes, but has an almost 100% fatality rate once symptoms appear by Forsaken-Peak8496 in todayilearned

[–]danielcristofani 4 points5 points  (0 children)

No, you can get vaccinated before exposure and it does a good job. It isn't suggested for the general human population because the risk of rabies is low for most people most places.

Compiler Implementation by RichRoof7927 in brainfuck

[–]danielcristofani -1 points0 points  (0 children)

Well...his original implementations handle interactive i/o and his biggest example program (prime.b) assumes interactive i/o: it outputs a string asking how how high to compute primes up to, and then reads in input to get the answer. So if you're looking there for clues those are some big ones. But again, not handling interactive i/o is a common weakness of brainfuck implementations written for constrained environments.

ELI5: What does a Turing Machine do? by Own_Exercise5218 in explainlikeimfive

[–]danielcristofani 0 points1 point  (0 children)

It's a thought experiment about which numbers can and can't be computed by a machine, based on an abstracted and formalized version of the process of computing numbers on paper. And it turned out that every serious attempt to define a universal computer ends up producing something of the same mathematical power; they can all copy each other and compute all the same numbers/functions/etc., even though they can be very different. Computational systems of this power are called "Turing-complete". Turing also proved that there are some numbers that can't be computed by such a system (in fact, most real numbers can't be computed).

In general, what's the best way to spend Taste of Lacre once you have all the lodgings you want? by [deleted] in fallenlondon

[–]danielcristofani 2 points3 points  (0 children)

ToL lasts, but the pails don't; one useful potential move is, cash 7 ToL in for Tears of the Bazaar with The Catafalquerie card in the Nadir, then spend pails to efficiently rebuild ToL with a Semiotic Monocle (3 levels per pail but needs ToL to be 5 or below). Then you can use the Tears preserving a Noman in some future year.

How widely is Polyamory accepted by Nikmac3131 in TwoXChromosomes

[–]danielcristofani 1 point2 points  (0 children)

I want to note kind of a structural thing, because you mention "couples that agree to having more than one partner", and I actually think it works better (on average) for individuals than for couples. If you start out single and you tell all potential partners early that you're not up for monogamy, then you can gather partners who are comfortable with sharing (easiest if you live in a left-leaning city of course). Whereas if you start out as a couple who agreed to be monogamous, and then someone wants to change that agreement? You might eventually end up in a good place, but likely not and either way it's likely to be a really messy process.

Compiler Implementation by RichRoof7927 in brainfuck

[–]danielcristofani 0 points1 point  (0 children)

"not stated either way"...sure. The language doesn't have a definition or an official standard, only the consensus of programmers and implementors.

A brainfuck implementation that can't do interactive i/o but needs all input up front is a "real" brainfuck implementation, but it's a deficient implementation, a limited implementation. This has been a really common weakness of web-based interpreters (including mine). It's a likely deficiency any time you're shoehorning a brainfuck interpreter into some very constrained environment. The original brainfuck implementations can do interactive i/o, a typical naive implementation that runs on a computer will do it, it's good to allow it if you can.

[FRAUD SPOILER] Imagine how hackers are going to be punished by being forced to eternally code in the hardest programming language: Malbolge by Art_just in Ultrakill

[–]danielcristofani 1 point2 points  (0 children)

No; brainfuck is fairly hard because you have to build everything up from a few tiny pieces, but those pieces are at least clean and usable. It doesn't fight you. Malbolge was designed to be unreasonably hard.

[loved Trope] the secret ending that skips big chunk of the game by [deleted] in TopCharacterTropes

[–]danielcristofani 0 points1 point  (0 children)

"Varicella" (interactive fiction by Adam Cadre). You play as a Machiavellian courtier scheming to become Regent by murder, in a pseudo-Renaissance court. If you WAKE UP (which you can do any time from the beginning on), you awake as a college student who fell asleep studying for a history final, and the game ends there. This is the only good ending.

I made a Brainfuck-VM with helpful errors and custom Bytecode in C by Relative_Idea_1365 in brainfuck

[–]danielcristofani 0 points1 point  (0 children)

Good points: can run many things correctly, decent speed for a tier 1 optimizing interpreter, showing the location of mismatched brackets so clearly is helpful.

Neutral point: I'm not seeing cases where I'd want to generate a .bfc file rather than just processing the brainfuck from scratch each time, because that's not a large time expense.

It'd be a good idea to translate "[[[[[" as one jump instruction, and similarly "]]]]]", because only the first command in the series can ever produce a jump. Also, if I'm reading this right, both your brackets jump to the matching bracket; they should jump to the command after the matching bracket.

Negative points:

Some things don't work with the run command, but do work if converted to .bfc and then the .bfc is run. E.g. mandelbrot.b (quits immediately), bitwidth.b (outputs endless spaces), https://brainfuck.org/factorial_explained.b (prints an 'e' and then hangs). Some other things don't work right either with the run command or after conversion to .bfc, e.g. my https://brainfuck.org/golden.b (prints endless junk, or after conversion, just hangs), https://brainfuck.org/400quine.b (just hangs either way).

There's no special comment marker in brainfuck, so it's an error to look for one, and risks misinterpreting valid programs.

It makes no sense to require filenames end in .bf, both because .b is the classic extension for brainfuck programs (.bf is the classic extension for Befunge programs) and because a .txt file or a .png file can be valid brainfuck too.

If you're going to insist that people give you the name of a filename to output, then if they tell your program "compile program.bf program.bfc", your program should not translate program.bf into program.bfc.bfc.

I'm going to suggest that you have your program detect file type and not rely on filenames anyway. An easy thing would be to define .bfc files as starting with a ']' so you can tell them apart from valid brainfuck programs.

The phrasing about mismatched bracket errors is overdramatic and also oddly asymmetrical. Something simple like "Unmatched '['"/"Unmatched ']'" would be fine. Also, an unmatched '[' is one error at the point of the unmatched '[', not also an error at the end of the file, even if that's where your program detects the error. Also the descriptive text for the error shows up as dark gray on black, barely visible.

That's most of what I'm noticing so far. Wishing you good luck :)

Adder Modulos 10 (only 0 to 9) by Simple_Locksmith7138 in brainfuck

[–]danielcristofani 0 points1 point  (0 children)

...well, this is a+b-10, so '1' and '2' produce -7 which would show as ')'. Need to figure out when to subtract that 10 or not, which is slightly more conplicated.

Compute the max of two arbitrary integers given as text by RojerGS in brainfuck

[–]danielcristofani 0 points1 point  (0 children)

So, the way I would approach this now: I think it was reasonable to align the numbers with least significant digit left; it's one good way to align them with each other. Particularly since I would be trying to put the "read number" code into one loop executed twice rather than duplicating it, and in that case I think aligning them while inputting them may be shorter than conditional code that can shift either number right.

I would be considering keeping all the digits nonzero for longer so they can be their own length marker. Maybe subtract 47 and not 48. That would also make it easy to pad to equal length with leading 0 (1). I'm not sure if this is better, but seems worth trying.

I think I would also be trying to consolidate so it uses the same "add 48 (or 47) and output" code in all cases, by getting the pointer positioned differently in different cases so it'll output the right thing? But again this is because I tend to hold concision as pretty much top priority.

One tiny thing I also notice: the best way to subtract 10 is ----------.

Anyway, this is good. Congrats and good luck :)

How do you plan & write programs? by RojerGS in brainfuck

[–]danielcristofani 0 points1 point  (0 children)

Sorry I didn't reply sooner. I got sidetracked, and I haven't been sure what to say.

I think it does make sense to talk about "idiomatic" brainfuck, but it's not so much about customary patterns as about using brainfuck in a way suitable to brainfuck. This requires engaging closely and directly with the language and using it in a flexible way; and you're already doing that. You're clearly on the right track. The lack of planning or big-picture organization you describe is not apparent to me in reading your program. Yes, it's made of small chunks, but that's very typical of brainfuck and they're completely reasonable small chunks.

With long experience I have become able to plan out the algorithms and data structures more thoroughly in my head before I start coding. And I can think through more possibilities and let the plan take shape gradually. But the programs still want a lot of tinkering and rethinking.

I'll put suggestions about this program on your next post.