Hacker Newsnew | past | comments | ask | show | jobs | submit | phantomics's commentslogin

Gulp is no longer required for the new Seed but Node still is. Unfortunately some JS libraries like Codemirror are only set up to build with Node. Node is used only to build these libraries and plays no part in the runtime.


Hi everyone, developer here. Seed is not abandoned but its original codebase has been; it is now in the process of being rebuilt. You can check on its progress in the revival branch of the repo.

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.


Wait, you created April, one of the most amazing hosted languages on Lisp just to learn Lisp? Wow! And here I am toiling over a simple CRUD library management app trying to figure out CLOS and it's not even going well.

April is a revelation and I'm putting it in my framework. APL reminds me of Leibniz's alphabet of concepts for his calculus ratiocinator. So gorgeous and efficient. I'm getting the keyboard.


Thanks, the utility of April was a big motivator as well, I used it in my Bloxl project (https://vimeo.com/935602359). Still, one of the reasons I focused on it as much as I did was because I knew that if I couldn't execute such a project well, I would have no chance to realize Seed. Implementing APL is a big undertaking but nonetheless one that has a clearly defined and testable goal. Seed is something with no reference to base a design off of, an objective toward which many paths appear to lead but only a few have the potential to fulfill in the best way. The challenge of such a project is on a completely different level from an APL compiler.


You either die an innovator, or you live long enough to see yourself become a Yahoo.


Nice little game. If your inspiration is Japanese '80s arcade shooters, it's worth taking a close look at them (and their 90s and 2000s sequels) to understood how they held the player's attention. A mistake I see in this game and many other Western shmups is giving the enemies too much health. Slowly chipping away at bad guys gets boring, usually the rule in these games is that small enemies die in 1-2 hits and larger enemies live just long enough to test whether you can evade their pattern of fire. The challenge comes more from weathering swarms of enemies than from any individual foe. Displaying lifebars above non-boss enemies is a sign it takes too long to destroy them. The pacing of arcade games is also instructive; levels usually last just a couple minutes and the enemy patterns are constantly varying.

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.


Does anyone else think it resembles Halley's Comet (Taito, 1986) [https://www.arcade-museum.com/game_detail.php?game_id=8064]?


Image processing is a fun use case. For example, here's a bit of Common Lisp using April and the Opticl library to create a mirrored meme image:

  (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...


As an array language developer I may be a bit heretical in the community for my view that array languages are a domain-specific tool, not a general-purpose tool. They are the best by far in their niche of working with arrays, but they can be harder to fit to some other kinds of tasks, especially when it comes to more semantic programming.

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.


> my APL compiler, April

Oh, I have to try this! APL is in the family tradition, I literally learned it from my mom. Probably the first programming language I sincerely enjoyed! I sure do miss the glyphs. Mom uses R now and often notes some things used to be easier with APL…


I'm using APL to build graphics for a hardware startup. You can see an example of the device, called Bloxl, and its graphics in this video:

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...


Great to reach this milestone with April. Since the linked YouTube presentation, its code base has changed by about 95%, I've fixed hundreds of bugs and added dozens of functions from Dyalog's online collection to its standard library. There's still plenty to be done and many possible applications of April, but this is the point where the compiler has substantially fulfilled my vision of what it should be.


This is something I go over in the video - an alloy of Lisp and APL works better than either language by itself.

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 is usable within Common Lisp. When writing a CL program, you can invoke APL code on arrays. For example:

(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.


It would be cool if it was implemented as a reader macro instead of just passing a string to a function.


Do it yourself! (Implementation loosely based on phantomics' comment below.)

    (defun april-reader (stream char)
      (declare (ignore char))
      `(april ,(read stream t nil t)))
    
    (set-macro-character #\⎕ #'april-reader)


You're probably gonna want something more complicated than that. Glancing at the github page it looks like at least the following need to be dealt with:

  (april "apl code") ; and april-f
  (april (with (stuff)) "apl code") ; and april-f
  (april-c "apl code" (input))
  (april-c (with (stuff)) "apl code" (input))


Yes, the above is a trivial implementation; handling multi-form input would need to be much more complex. Thankfully, for simple one-liners, you'll likely want either April literals (implemented above) or April anonymous functions, both of which won't take additional arguments; you should be able to implement both as simple reader macros.


Wouldn't be too hard to do, someone in the video suggested a #⎕ reader macro followed by APL. Like take '#⎕string' then expand that to '(april "string")'.

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.


Another option is to load APL source from a file.

(april-load #P"/path/to/code.apl")

Then you can have files of pure APL code with no Lisp hanging around.


> Consider the amount of code this would take in CL.

I don't really read APL - but isn't this just a map/reduce over the pixels? - maybe (length (remove-duplicates 'pixel-data)) or some such?


The pixels aren't singular values, the image is a height×width×3 array of 8-bit integers. The third dimension is the three RGB values for each pixel. The bulk of the string, the "(3⍴2*8)⊥3 1 2⍉⍵" part, converts the array into a height×width matrix of 24-bit integers representing the colors. Once you have a matrix M, "⍴∪,M" is all the code needed to count the unique values.


Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: