Live data from Hacker News

April, an APL Compiler for Common Lisp [video]

youtube.com

11–20 of 24 posts

Re: April, an APL Compiler for Common Lisp [video]

#11
post #9
post #7

Earlier quoted context omitted.

> 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. What accounts for this discrepancy?

-Common Lisp vs C/C++ -April implements the language and just punts to CL for all the I/O and system level stuff. Like it doesn't have to implement a REPL, or a line editor or APL workspace files/array stores.

Thanks. I'm guessing (based on my knowledge of J and all its optimizations/special forms) that Dyalog APL would still be more performant too? I didn't see it mentioned on the GH README.

Re: April, an APL Compiler for Common Lisp [video]

#12
post #8

Earlier quoted context omitted.

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)

Re: April, an APL Compiler for Common Lisp [video]

#13
post #11
post #9

Earlier quoted context omitted.

-Common Lisp vs C/C++ -April implements the language and just punts to CL for all the I/O and system level stuff. Like it doesn't have to implement a REPL, or a line editor or APL workspace files/array stores.

Thanks. I'm guessing (based on my knowledge of J and all its optimizations/special forms) that Dyalog APL would still be more performant too? I didn't see it mentioned on the GH README.

Yes, the talk mentions that Dyalog is still much more performant, given how much time and effort has been spent on optimizing it.

Re: April, an APL Compiler for Common Lisp [video]

#14
post #7

Since the video's quite long, here are some basics on April. 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…

> 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. What accounts for this discrepancy?

A ways into the video it says the core Dyalog interpreter is about 100KLOC, with the rest being GUI code and interop such as file handling and formats, cross-platform support, .NET interop, and so on. If the 100k figure surprises you then what you are missing is just how deep array optimization is. For example, searching through an array will use an SSSE3 table lookup for 1-byte elements, a different table for 2-byte elements, and several different kinds of hash tables for other types. I tried to give a sense of the scale of this sort of thing in the first slide of my Dyalog '19 talk on Reductions (https://www.youtube.com/watch?v=TqmpSP8Knvg). You can write pages and pages of code and still there will be a way to speed up a common operation substantially.

By working on multidimensional arrays, APL expands the range of computations that are accessible to optimization. I think the writer of a scalar compiler like C would generally be happy making a single loop as fast as possible. APL immediately makes the implementer think about what happens if there are many axes (each of which is equivalent to a nested loop) even if the later axes (inner loops) are small.

Re: April, an APL Compiler for Common Lisp [video]

#15
post #8

Earlier quoted context omitted.

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

Re: April, an APL Compiler for Common Lisp [video]

#16

Earlier quoted context omitted.

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.

Re: April, an APL Compiler for Common Lisp [video]

#17
post #8

Earlier quoted context omitted.

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.

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.

Re: April, an APL Compiler for Common Lisp [video]

#18
post #3

Without watching the video, can we guess correctly that "for Common Lisp" means "in Common Lisp"? Or is it really meant for use within Common Lisp programs?

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.

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

Re: April, an APL Compiler for Common Lisp [video]

#19
post #18

Earlier quoted context omitted.

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.

> 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.
Post reply on HN