Just wanted to say that I think your rendition of Zellige is really nice, thank you for sharing! This is a very cool drawing language, and I think your art here is a really solid example of how creative you can be even with very limited tools.
I made a pinwheel, which is maybe not that exciting, but was a lot of fun for me. I like the bracket syntax a lot, and figuring out how to make this work actually recaptures some of the old sense of exploration and fun that I felt before programming was my day job.
Thanks, please consider sharing your pinwheel, I'm sure it was awesome to make too!
You're touching on an important point. I tried to figure out CFR[] by trial and error and it was a lot of fun, the kind of which I didn't feel for a long time. I think this boils down to two things:
- Bounded complexity, which encourages you to explore it to its fullest
- Immediate feedback, the result is not disconnected from the act of editing the code, so your iteration cycle is super short.
It's not very interesting by itself (it just fills the whole screen with white) but you get cool-looking visualisations of its fractal-like structure by putting "C" at different points of the opening brackets.
Naive micro-optimization of your program (namely, things like FF is 1 char shorter than [F]) got that down to 40 chars:
[[[[[[[[[[[[[[[FF]]]]]]]RRF[RRR]]]]]]]]]
I then found a solution in 37 which uses a slightly different approach (namely, create a pattern that spans the full X and Y output space, then shift it by one step each iteration):
> I wonder what an AI could design with instructions for how to use this.
I tried asking chatGPT to use it, removing the colour instruction to reduce complexity.
After clarifying what each instructions does and providing some documented examples, it could write syntactically valid programs, but they never drew the shape or pattern it explained they would.
I think the language being repetitive strings of characters doesn't mesh well with predicting tokens.
Yes, this was reported at https://news.ycombinator.com/item?id=37969444 and I got a fix out shortly afterward. Please hard-refresh the page (ctrl+F5, cmd+shift+r, etc.) and let me know if you still see this issue. Thank you for highlighting this problem!
- If you raised the bit limit and added a "skip" option (ability the move cursor forward without drawing) you could potentially render simple 3d objects and run Doom by converting objects to commands
- You could implement a function that simplifies your existing inputs, so: FFFF becomes [[F]]
Cool! I love the absolute minimalism, it forces some creativity. I don't know if it would violate the spirit of the language to add some kind of state or conditional to make it Turing-complete.
Oops! I like to use the back button too. While implementing the distributable link feature, I overlooked that this is breaking the back button behaviour.
Thanks for pointing this out! I have pushed a fix for it just now. Please hard-refresh the page (ctrl+F5, cmd+shift+r, etc.) and let me know if you still see issues.
The GitHub link is helpful, it might be useful to include what each command does at the bottom of the page so users don’t have to go to the GitHub page to figure it out
Sure, but it also added 50 entries to my browsing history. You can use the browser history API to only replace the state instead of pushing new states on.
Not OP, but I don't see why one would need to parse this at all. You can just step through the characters one byte at a time and execute them, using only a stack memory for return addresses to implement the [] behavior. No syntax tree needed.
Thanks! Glad you like it. The sibling comment by majewsky is spot on. There is not much parsing going on. Every character is read one at a time and the turtle's state is changed. Indeed the "[" and "]" commands are implemented with a stack.
Is there a measure of something being "canvas complete" where you can construct "any bitmap" given it? Analogous to Turing complete but limited to drawing on a bitmap canvas.
This is so cool by the way! I love this! Thank you for making this!! :)
Ha! I was thinking more "a drawing language" like the one in the Show HN post. So cool!
I was wondering if there are other languages like these, and a measure analogous to Turing completeness, but for "canvas completeness" for drawing any bitmap on a canvas! :)
Thank you for sharing this feedback. I have updated the implementation and added a '?' button now that can be pressed on a smartphone to bring up a help screen. The help screen has brief descriptions about each command.
"Awk-Apl SOLIDs, a logistician's tty take on analytic geometry"(unpublished) resources that might be of interest:
Techinques in the unpublished report make use of some solid applied analytic geometry regessions (byte sized pixels[2][3]) using sources of integer sequence[1] for a different mechanical engineering take on what CFR[] does.
Although, the overall goal was to maximize font type useage[4][6] while minimizing IRQ/type ball interuptions[5].
aka mechanical/impressionist e-ink. Takes less effort to generate striking details with CFR[].
a few noteable websites :
The Cinco Library Encyclopedia of Numbers : https://www.youtube.com/watch?v=rVtHrgdcvZA
On-Line Encyclopedia of Inter Sequences : https://en.wikipedia.org/wiki/On-Line_Encyclopedia_of_Integer_Sequences
offline/local dabase intdb : https://github.com/popey456963/intdb
Are you referring to the short list at the top of the README on GitHub? That list does not provide "syntax definitions". That's just a quick introduction about what is about to come.
The command "F" does not draw a pixel and move forward. Instead "F" moves forward first and then draws a cell.
> [ ... ] (loop): anything inside this is executed twice
The control flow command "[" can be written without a corresponding "]". For example "[", "[F", "[[F", etc. are valid CFR[] inputs. Again, the section of the README I have linked to above defines what "[" and what "]" are.
Barely anyone is going to go to the github, especially outside of HN, and only some of those people are going to read past the first image, so it's important that you get the most important information out there immediately. I glanced at the extended explanation and decided it would be faster to figure it out by putting stuff in the website. The instant visual feedback means you don't need to tell users every nuance of every command, but you do need to pick the specific details that users can use to learn everything else.
I have updated the implementation to incorporate your feedback as much as possible while maintaining accuracy in the command descriptions. Now there is also a new help screen which can be invoked by typing '?'.
I am hoping the information in the new help screen will make the commands easier to understand. However, if you or anyone has better ideas about describing the commands, please feel free to send pull requests.
Thank you for playing with this tool and for offering your feedback! It has been very helpful in refining the command descriptions.
> For example "[", "[F", "[[F", etc. are valid CFR[] inputs.
Are those different from just "F"?
If not, even if those are technically valid syntax, op's explanation seems clearer. I was confused by the README definition too and came to op's conclusion after experimenting for a while.
If they are not equivalent to just "F" I still don't get the distinction so the README definition is not very good considering it confused at least both op and me.
(This is meant as constructive criticism, I'm having a lot of fun playing with this.)
Thanks for the feedback. The code examples "[F" and "[[F" both paint one cell but the code "[" produces no visual change, so in that sense there is a difference between them.
Between "[F" and "[[F", there is no visual difference. The command "[" is a control flow command that does not alter the state of the canvas or the invisible turtle. Instead it merely marks the current position in the code as the beginning of a block. The execution continues normally after "[" regardless of whether there is a corresponding closing "]" or not. However, if a corresponding "]" is found, then the execution jumps back to the corresponding "[" and executes the enclosed block once more. This produces the effect of a loop that executes twice. For most drawing purposes the code bounded by "[" and "]" indeed behaves like a loop that executes twice.
I have updated the README to make this clearer. However, I am open to improving the README further if there are better suggestions. Pull requests are welcome too.
My best rendition (would have been better if there was a counter clockwise rotation, improvements to my code are welcome!):
[[FFFFFFR[[CFFFFF]]][[[[[[[FF]]]]RR[[F[CC[RC[FFFFFF]]RFFFFF[RFFFFF][R[CFFFFFF]]]]]R[[[[FFFFFFFFFFFFFFFFFFFFF]]]]][[FFFFFFFFF]]]]
[0]: https://zellige.info/