libera/#commonlisp - IRC Chatlog
Search
10:15:19
beach
DEFGENERIC forms are (unfortunately) optional, and omitting them does not prevent extensions. But I always include those forms, if only to give an explicit name to the parameters so that they are visible in an IDE or in SLIME.
10:16:37
beach
I wrote "unfortunately", because it is one of those design mistakes that can make life harder for the programmer. A simple typo in a DEFMETHOD form will silently define another generic function. Fun debugging stuff like that.
10:17:57
beach
We have gotten rid of most such design mistakes over the years. Fortran contained lots of those (maybe still does?) and the same thing holds for C.
10:18:36
bitblit1
So, I should make close, render, and other important functions methods of my canonical class?
10:18:52
loke[m]
beach: That's why you have to put `implicit none` in the beginning of your fortran source ;-)
10:31:02
splittist
bitblit1: a literal CLOSE is going to conflict with CL:CLOSE if (as seems likely) you've USEd the cl package. But you probably meant CLOSE-WINDOW (:
10:34:32
bitblit1
Ohhh, yeah I was lliterally just trying to debug that problem, thanks a lot splittist
10:41:22
splittist
Has anyone been working on a baserow/smartsheet style thing (web-based, user-configurable db frontend) in lisp?
10:44:13
phantomics
splittist: I built a system that's basically a web-based visualizer for CL forms and systems that includes a spreadsheet module
10:45:50
splittist
phantomics: possibly even better. The forms/systems were persisted as source, in the image, with backups, all of the above, or I'm completely misunderstanding things (:
10:46:49
phantomics
The forms and systems were persisted as source, specifically ASDF systems were the top-level division
10:47:53
phantomics
It could have been used as a DB frontend, just wasn't limited to that. The project is dormant with plans to build a new version once some of my other dev goals are reached
10:48:43
phantomics
It's called Seed, you could say it was a very different kind of IDE with support for multiple visual programming frontends whose input composed to CL source code in an ASDF system
10:50:08
splittist
phantomics: cool. (I don't want to think about how many 'dev goals' I have on the stack...)
10:53:13
phantomics
Hi beach, I heard you had a project to build an assembler that's portable across CLs, is that correct?
11:01:31
bitblit1
The safety 3 and other optimizations made my life sooooo much easier... hahaha I was coding with a (little) pain for so long
11:01:48
beach
phantomics: I don't see that there is any implementation-specific code in an assembler, so I don't see why any care needs to be taken to make it portable.
11:04:21
phantomics
Very cool, so there's potential to expand it to other architectures as well? Could it be used to build functions and load them in a running CL instance the way you would any other function?
11:05:57
phantomics
About implementations and assemblers: I've been working with SBCL's vop system to do JIT assembly of optimized kernels, one caveat with the vops is that there are some registers you shouldn't use because SBCL uses them and you can clobber values that are needed by the compiler
11:06:02
beach
Yes, I want to add support for RISC-V, but most architectures are trivial compared to x86. Whether you could use it in an implementation would depend on how that implementation is designed, I would think.
11:07:15
phantomics
For instance, in 2.3.0 putting anything in R12 and R13 will cause memory faults, I was able to avoid this by putting them on the stack for the duration of the function and popping them at the end, but I was advised not to do this and also that the restricted registers may change from version to version of SBCL
11:07:17
beach
phantomics: I had no ambition to create an assembler for any existing implementation, so I didn't give any particular thought to that aspect.
11:07:45
hayley
Yes, don't do that. From memory, R12 is used for thread-local state, and R13 for the card map used by the garbage collector.
11:08:17
hayley
Are you performing your own register allocation? I think the register allocation done for VOPs would already avoid those registers.
11:08:34
phantomics
So in order to assemble loadable functions you need to know the gotchas for a given implementation, and those may change between versions.
11:09:39
phantomics
hayley: I was experimenting with manual allocation, now I only manually allocate the A and D registers because you need to handle them specifically due to their role with MUL, DIV and some other stuff
11:09:50
beach
phantomics: Sure, an assembler just takes representations of instructions (in this case as instances of standard classes) and produces a sequence of bytes. It is up to the user to put in the right instructions and the right arguments to those instructions, including the registers.
11:12:12
phantomics
Perhaps CL implementers could include a parameter listing the registers that shouldn't be changed and any other gotchas that an assembler needs to avoid on a given impl
11:14:55
hayley
It would also be necessary to have a way to install a function from a byte vector, which might be awkward for ECL, and more awkward for ABCL.
11:15:56
phantomics
The performance of the JIT-built vops has been amazing, April's performance for the specific operations I've optimized may be the fastest of all CPU-based APLs, unfortunately it's limited to SBCL for now
11:16:58
beach
phantomics: It is not that simple. Some registers could be used for other things in some parts of the code, but not in other parts of the code.
11:17:20
hayley
(See <https://www.softwarepreservation.org/projects/apl/Papers/DYNAMICINCREMENTAL> for reference)
11:19:08
phantomics
Short answer: yes. April has been rebuilt implementing lazy evaluation in the last year. The code generated by the compiler produces a tree of CLOS objects whose methods generate an optimized function for transforming an array
11:19:30
hayley
(Or, in a Common Lisp context, I might as well ask if it's more like Petalisp (which does all the data flow analysis, and compiles larger "kernels") or numcl (with functions individually hand-tuned).)
11:20:45
phantomics
One of the most dramatic things it lets you do is for example (april-f "5 5↑¯20 ¯20↓80 80↓3/20⌽2000000 2000000⍴⍳10*10")
11:21:30
phantomics
This is creating a 2 million square matrix, rotating, stretching and cropping the entire thing, then taking the upper-left 5x5 of it
11:22:51
phantomics
Because it starts from the end and works backwards only the 25 output elements are actually computed
11:24:33
phantomics
The array restructuring functions work by processing array indices as encoded integers. For instance, if you have a 3D array whose dimensions are all under 256, its coordinates can be encoded in a 32-bit int. Coordinates (1, 2, 3) can be encoded as #x00010203 for example
11:25:52
phantomics
So for instance if you're doing a take of the array which crops off 10 elements on all sides, all you need to do is add #x000A0A0A to each coordinate value
11:26:31
phantomics
You can chain these operations together to do multiple array transforms in a single loop without writing the intermediate arrays into memory
11:28:50
phantomics
Using CLOS initialize-instance and metaclass allocator overrides, it's also possible to obviate some classes when they're created
11:29:29
phantomics
For example, 3⌽3⌽X becomes 6⌽X and ⍉⍉A becomes just A because two successive permutes cancel each other
11:59:59
bitblit1
phantomics: Not really, just random stuff. I am making a window manager called blitter-wm and other small projects like a calculator for CLOSOS.
12:05:10
bitblit1
Not really, just for myself. I was tired of StumpWM being wierd and unmaintined. Wanted a simple X window manager entirely in CL which would be super customizable. However, this was my secret preperation for making a WM for CLOSOS
12:14:01
phantomics
If you could get some workflow display logic in there would be cool, like being able to spawn collections of windows and desktops for a specific task
12:14:49
bitblit1
phantomics: Could you elaborate a little more? I would love suggestions! Also, you can be sure to add them as TODOs (issues in git repo)
12:16:55
phantomics
Say I want to define a task like video editing, which will involve the video editor, Inkscape for designing caption graphics and Audacity for creating the audio track. It will start those programs and display them in a specific defined layout with constraints based on the monitor form factor
12:18:07
phantomics
And also give a set of key shortcuts for moving between them. Another simpler workflow could be "image editing with April" where I have an Emacs window for interacting with April and an image viewer window for viewing the image I'm generating. This can be done entirely in Emacs but it could also be a workflow based on multiple desktop apps
12:20:54
phantomics
I could put a TODO but it's not very concrete as a goal, something more specific that you could improve over Gnome/KDE/xfce is configuring keyboard shortcuts for doing different things, a Lisp-based config would be great for stuff like that with unlimited options
12:30:02
phantomics
You may want to look into the Cassowary constraint solver for layout logic: https://github.com/slightlyoff/cassowary.js, https://constraints.cs.washington.edu/cassowary/
12:47:18
phantomics
Here's a discussion of Cassowary and some other algos: https://news.ycombinator.com/item?id=13124584
13:01:57
bitblit1
How do I create a macro wrapper around a function which is sensitive to keyword arguments passed to it effeciently? For example:
13:02:25
bitblit1
I have a function whose argument list looks like this: `(&key (host "") (display 0 display-p) (screen 0 screen-p))`
13:03:00
bitblit1
I want to create a macro/function which would run it in a separate thread and take the exact arguments
13:09:34
flip214
bitblit1: you can use &rest to capture all arguments and relay them on; but be aware that a macro gets _unevaluated_ arguments whereas the function gets _evaluated_ args
13:13:42
flip214
bitblit1: see the last example on http://www.lispworks.com/documentation/HyperSpec/Body/03_daf.htm