phantomics
Joined 6 years ago
Joined 6 years ago
Here is a quick video demo of the old Seed: https://vimeo.com/237947324?fl=pl&fe=sh
You can see my LispNYC presentation of it here: https://www.youtube.com/watch?v=nnec6_7PWkc
In my initial attempt at Seed I didn't yet understand Common Lisp well enough. That's part of the reason I wrote the April APL compiler between now and then, to gain enough understanding of the fundamentals to pursue such a comprehensive project.
The original Seed was based on React.js for the frontend and attempted to bypass textual Lisp programming as much as possible. This was an ambitions goal and React wasn't the right fit for such a project; it's a heavy system that's undergone rapid development over the years and Seed needs something that's lighter and can function more as a simple outgrowth of the underlying Lisp code. The current Seed codebase uses HTMX and Alpine.js as its main frontend tools, and the model also isn't tightly coupled to browser interfaces; it could later be possible to build terminal UIs and desktop interfaces with the same set of UI classes.
Regarding CLOG, Seed and CLOG are both interface-oriented projects but beyond that they're quite different. The idea of CLOG is a toolkit to specify interfaces with CL; it offers you many elements you can build into interface. The idea of Seed is to extend the manifestation of symbolic expressions beyond text, to have list structures that manifest interface elements that a person can interact with to create and modify programs.
For instance, you can have a series of CL function calls that perform transformations on an image, like lightening or blurring it. Using Seed's model, this list of function calls can be represented in a user interface similar to the layer lists seen in graphics software like GIMP and Photoshop. With the right combination of interface elements it could eventually be possible to duplicate the functionality of these image editing tools in a general-purpose programming platform. It would be like building GIMP into Emacs with the ability to instantly open, edit, and save a changed version of any drawing tool and have it show up in the toolbar.
This model guides the development of both the user interface and the underlying Lisp code, so it's about more than building an interface toolkit. It's about the UI as the outgrowth of the underlying software structure.
Feel free to drop more questions here.
Other than that the music and aesthetics are great, though there is some funny aliasing of sprites and JPEG artifacts in the backgrounds. The key to this kind of aesthetic is a crisp look.
(opticl:write-png-file
"~/out.png" (april-c "2 0∘{(x s)←⍺←2 0 ⋄ (⌽[x],[x]⊢)⌽[x]⍣s⊢⍵↓[x]⍨(1-2×s)×⌊2÷⍨x⊃⍴⍵}"
(opticl:read-png-file "~/in.png")))
The 2 0 at the start of the APL line above controls the mirroring behavior. The second number can be set to 0 or 1 to choose which side of the image to mirror, while the 2 sets the axis along which to mirror. This will be 1 or 2 for a raster image but this function can mirror any rank of array on any axis.April was used to teach image filtering in a programming class for middle-schoolers, you can see a summary in this video: https://vimeo.com/504928819
For more APL-driven graphics, April's repo includes an ncurses demo featuring a convolution kernel powered by ⌺, the stencil operator: https://github.com/phantomics/april/tree/master/demos/ncurse...
That's why my APL compiler, April (https://github.com/phantomics/april), can be called within Common Lisp with CL data structures as its input and output. It's also trivial to port functions from CL and its libraries into an April workspace. You can see an example on page 2 of this paper: https://zenodo.org/record/6381963
In this way April puts the entire CL ecosystem at your fingertips. If you want to do something like making HTTP requests or ingesting XML files, you can write a function to do it and express the specific parameters for your use case in CL, and then have the function available within April using a simple monadic/dyadic argument API. This can sidestep the need to port every necessary library into APL itself.
https://youtube.com/watch?v=AUEIgfj9koc
Related HN story: https://news.ycombinator.com/item?id=24434717
More pics and videos at: https://bloxl.co
My April APL compiler has a terminal graphics application as one of its demos, which you can see in this folder: https://github.com/phantomics/april/tree/master/demos/ncurse...
Lisp excels at creating semantic and logical patterns. Macros allow you to build reader-friendly data structures that transform into working code. In the April repo, check out spec.lisp which expresses the top-level spec for the language. Most language implementations don't have this kind of centralized, readable spec where all the language's features and conventions are laid out in one file. The unit tests in this file even constitute a demonstration of what each function and operator does.
APL is for writing algorithms. Data transformations that would take pages of code in other languages can be accomplished with one line of APL. It's trivial to do things like find the color palette of an image and create a copy of the image with another color palette swapped in. Signal processing, machine learning and similar tasks are a snap.
When I created the animations for the Bloxl device, I created a Lisp-based spec for animations with bits of embedded APL. Most animation effects are standardized and have Lisp functions implementing them. However, many patterns have unique algorithms used to implement effects just for that pattern. If I were using Lisp, I would have two choices as to how to do this:
1. Write the unique code into the spec for each pattern, bloating the animation specs with tons of loops to create the special effect. An individual animation spec may go from 12 lines to 60 lines or more doing this.
2. Write a function to implement the special effect. All the special effect functions would have to go into another file somewhere. The animation packages would become bloated with many functions that are only used in one place.
Instead, I can implement the unique effects in APL. It only adds one more line to the spec and avoids both kinds of code bloat described above.
(april-load #P"/path/to/code.apl")
Then you can have files of pure APL code with no Lisp hanging around.
But April has many ways of passing options and external data for the compiled code to operate upon, and implementing a reader macro system that would support all those parameters would be complicated and require developers to learn a bunch of new syntax in order to use April with reader macros.
(april-c "{⍴∪,(3⍴2*8)⊥3 1 2⍉⍵}" (opticl:read-png-file "/path/to/image.png"))
This snippet uses the opticl library to load a PNG file, and then uses April to count the number of unique colors in the image. Consider the amount of code this would take in CL.
Repo: https://github.com/phantomics/april
April compiles APL to Common Lisp. It has almost all of the lexical functions and operators featured in Dyalog APL, the leading commercial APL interpreter and the most featureful APL implementation. It has many more features than the FOSS GNU APL, which is based on the old IBM APL2.
Dyalog APL's source code is about 500KLOC according to Dyalog's staff. GNU APL is over 100KLOC per its homepage. April's .lisp files currently stand at 6350LOC.
APL interpreters have traditionally been hard to connect to external data sources. Because APL is typically implemented as an interpreter, any connection to a database or other external system needs to be built into that interpreter as a plugin. April is called from within a Lisp program and you can pass it any array-formatted data. You can use CL libraries to read from any database or other source, format the data as an array and pass it to April for processing.
April takes some features from the k language, including ($[oneorzero;1;0]) if-statements and (g←{[a;b;c]a+b×c} ⋄ g[1;2;3]) n-argument functions.
April is extensible - you can easily create an extension to the language with more functions and operators, and you can also re-implement the utility functions that are used to parse and compile the language. The language is designed from the ground up to support extension. There is also a framework to extend the compiler to optimize common idioms, for instance ⊃⌽,200 200 200⍴⍳9 is optimized to just fetch the last row-major-ordered element of the big array instead of actually taking the time and memory to ravel and reverse it.
The second half of the video features a preview of a hardware startup called Bloxl that's powered by Common Lisp and April. Bloxl is a big transparent block wall with LEDs inside the light up to create pixel graphics. April was used to build the animations that run on Bloxl.
https://bloxl.co/
https://github.com/phantomics/april