Please sign in to access this page
FIXAPL is a programming language inspired by APL, re-imagined using fixed-arity functions all the way down. APL is a language which uses special characters as function names and multidimensional arrays as the primary datatype, allowing for very concise and elegant code. Fixed-arity means that contrary to other APL dialects, there are no variadic functions. That seems like it would be a disadvantage, but it actually provides a lot of benefits, aiding readability of the language as well as providing more expressive tacit (point-free) forms of construction.
jim
Check their projects out: Authly, Cancer Prediction Python ML, Programming Language (custom), Gina, Dropboard
Once you ship this you can't edit the description of the project, but you'll be able to add more devlogs and re-ship it as you add new features!
I added namespaces and scoping to the language, allowing for some primitive object-oriented patterns. I also added the function ⪫ arity
which gives the number of arguments a function takes, and improved structural under.
I added a pretty-printing system for arrays in FIXAPL. I got some feedback from dzaima, the implementer of CBQN, to help improve the system and handle some special cases which weren't dealt with properly in my initial attempt. I also made this feature toggleable with a setting.
I added inline assignments via ↤
. These let you assign values to names within an expression so you can use the value again on that line. I also rewrote the entire system for expression parsing to be a bit more accurate to the arity patterns system I was going for and actually parse left-to-right.
I renamed the dfn arguments x and y to alpha and omega, like in APL. This involved changing a lot of error messages. I also improved FIXAPL's handling of high Unicode codepoints in string and character literals. Additionally, I changed identifiers to allow numbers in them, and did some design work on an inline variables system I'm planning.
I added the execute and format functions. Execute takes a string or array of strings and evaluates each one as a FIXAPL expression. Format takes any value and returns a string attempting to make valid FIXAPL code for it.
I added the ⎊ catch
dyadic modifier, which calls the left function, then calls the right function if the former raised an error.
I fixed the scan function to be like BQN's. I had implemented it like Uiua before, but I hadn't realized that it would cause some cases to break.
I spent most of this time trying in vain to make a left-fill-merge function. I couldn't figure out how to implement it in the general case so instead I just did some refactoring of a lot of primitives.
I added the ⬚ fill-merge
function which takes an array and a fill-value and merges the elements of the array into a new array by filling in positions with the fill-value when necessary. This is a function I've never seen in another array language, though that's partially because they have other solutions to the same root problem. I also fixed up the settings UI to look a bit better, and fixed a bug with under.
I added the ⎕Text
function to render text to an image. The left argument specifies the font size, family, foreground color, and background color. I also added a setting to switch the default font for ⎕Text
, defaulting to TinyAPL386 Unicode.
I changed iota given a list to be like APL/BQN, generating multidimensional indices, rather than just reshaping the flat indices.
I improved the display of functions in the REPL. Before they just showed as or , depending on their arity. Now, they actually show the parsed expression tree.
I made the glyph for transpose display with a trans pride flag. This feature is copied from the Uiua site because it's awesome.
I added a download button for images on hover. Currently only PNG downloads are supported, maybe I'll add some other formats in the future. Especially GIF/APNG if I decide to allow animated images.
I added a setting to automatically show images for any values which can be shown as images. It checks for images of size 30x30 or smaller. If you need to show smaller images than that, use quad Img like normal.
I improved the input-prompt interface. Before, it just used the browser's alert popup, which looked pretty bad. Now it actually shows up inline with the rest of the program output.
I restructured the REPL interface to evaluate the code in a background thread instead of the main thread, so the rest of the UI isn't blocked. This took a long time because there were a ton of weird bugs I was running into with Vite, most of which I'm pretty sure weren't my fault. (I also added a settings indicator)
I added a setting called display times, which shows how much time was spent calculating the results. I also fixed several bugs with primitives, and a tricky one with bindings being re-called every time they were accessed. I also spent time writing a program to draw a Mandelbrot set fractal, which you can see in the image below. It renders 25 iterations on a 200x200 plane in 3.2s.
I added support for RGB(A) images. They're represented by rank-3 arrays of numbers. The last axis can be 2 for grayscale with alpha channel, 3 for RGB, or 4 for RGBA. Rank-2 arrays of numbers still work as grayscale images.
I added the ⎕ShowImage
function which takes a 2d array of numbers in 0..1 and displays a grayscale image where 1 is white and 0 is black. In the future I'm planning to add RGBA images too.
I added the quad Sleep, which halts execution for the given number of seconds. This required refactoring the entire codebase to use async functions everywhere, which took a long time. I also did a bunch of bugfixes.
I worked for around four hours, not sure why Hackatime says 20m.
I fixed a lot of bugs and added quads to the language. The only supported quads for now are Print and Prompt, but I have a few more planned.
I made expressions have different roles. Previously, both 1 + 2
and 1 (0⊃⟨+⟩) 2
would work and come out to 3
, but the latter is very weird and means you can end up with expressions which were parsed differently based on the values of their tines at runtime. Now, only the former works, and if you want to call a function from an expression, you have to specify its arity with ₀ subject
, ₁ monad
, and ₂ dyad
.
I added the function ⊚ where
to the language, which gives a list of the indices of ones in the input, with an extension for non-boolean arrays. I am planning to extend this behavior to higher rank arrays in the future. The main time spent here, though, was in fixing a bug with a function used a lot internally, since I had to make changes to a ton of functions. In the screenshot you can see how this bug previously affected the structures of arrays and how it has been remedied.
I added dfns (dynamic functions) to the language. This is a syntax for writing functions with lexically scoped arguments -- x being the left argument and y the right argument.
The snippet in the screenshot defines a function In
to check if the array y contains items of the array x, and uses it to filter the numbers from 2 to 30 by whether they are prime.