libera/#commonlisp - IRC Chatlog
Search
6:23:09
pjb
semz: good question (reuse of conditions). 1- we can signal the same condition several times. 2- most condition classes in the standard don't have slot writers (therefore in a new situation, there's no standard API to mutate it, but nothing prevents an implementation to have and do it). 3- usually, conditions are not collected, ie. if a condition was mutated, this would have no consequence, because nobody keeps references to old conditions.
6:25:00
pjb
semz: so in the spirit of the standard, it would be best if the condition was pre-allocated, but not reused. It could be allocated when the garbage collector can free enough memory for it. But it would be preferable to allocate a new one each time it's signaled.
6:25:59
pjb
while conditions are not usually collected, this is something that is perfectly conceivable: you could keep reference to old conditions in an object-oriented logging system.
6:40:49
specbot
Resignaling a Condition: http://www.lispworks.com/reference/HyperSpec/Body/09_adaa.htm
7:00:26
pjb
Alfr: thank you. Indeed. The problem is that the code that signals a condition cannot know when the handling of the condition is finished. It's definitely not when we're out of a handler-bind, but even not when we're out of a handler-case. For example, the handler could store the condition (with the situation that led to its signaling embedded in it), and process it later.
7:00:54
pjb
So indeed, conditions can be pre-allocated, but they should be used for a single situation.
7:12:11
pjb
semz: note that when a storage-condition occurs, the condition object is not the only object that needs to be allocated. We may also need to allocate some string (error message), some bignum (memory size, etc), and some other temporary object. Therefore it's probably best managed by reserving some memory zone where to allocate those objects, at the level of the memory manager.
7:33:58
greyrat
I am trying to write a one-off "macro" without using an actual macro. But `eval' seems to evaluate its input in the global scope. How do I do this idiomatically?
7:38:32
greyrat
I didn't use a pastebin because it takes two seconds for the site to load for me, so I really don't like opening webpages when I don't have to. I'll use pastebins in the future.
7:39:01
moon-child
you should be able to configure your text editor to automatically post some region to a paste site
7:43:07
moon-child
the compiler is less constrained if it is not required to be able to dynamically materialise a location for a given variable
7:43:20
beach
greyrat: What moon-child said. If that were possible, the compiler could not apply certain optimizations, such as eliminating dead variables.
7:45:04
moon-child
eliminating dead variables doesn't matter _that_ much--just a bit of extra stack space. But any sort of constant propagation or type analysis would be completely killed
7:48:19
beach
Sort of. If the variable is in a register, it may have to be spilled if it is considered live.
8:05:20
hayley
One trick I've done (which I think is a bit famous for happening frequently in SBCL sources) is to write a form like (macrolet ((frob-it () code-generation-stuff-here)) (frob-it)).
8:06:57
hayley
I recall one person wrote a macro for this pattern, and called it ETOUQ (backwards QUOTE).
8:09:15
greyrat
Okay, I wrote a macro. Is there any way to "map" the macro on a list? Sth like `(mapcar #'to-int '(year month day))' where `to-int' is a macro.
8:11:38
moon-child
(could make it a parameter. (defmacro stuff (&rest vars) ... iterate over vars) (stuff year month day)
8:18:17
greyrat
moon-child: Thanks. This seems awfully redundant and non-composable though. Why can't there be a general way to iterate a macro over symbols?
8:19:34
moon-child
greyrat: we've already established that this is 'one-off'. Why should it need to compose?
8:20:13
moon-child
(in fact, I don't entirely see why it composes much worse than any other solution. But.)
8:20:28
greyrat
moon-child: I would need to repeat the boilerplate for iterating over multiple arguments in ALL my oneoff macros, which is a lot of repetition.
8:21:40
moon-child
you can easily write a macro for writing one-off macros. Beyond that, it seems likely to me there is an alternate organization that would work better, but without looking at the code I cannot supply it
8:23:03
greyrat
moon-child: Can I write a macro that expands `(macro-iter some-macro a b c)' to `(progn (some-macro a) (some-macro b) ...)'? I guess this should be doable, and will resolve my problems.
8:24:37
moon-child
(defmacro ctmap (m &rest args) `(progn ,@(loop for arg in args collect `(m ,arg)))) or some such
8:38:45
greyrat
moon-child: Is it possible to add optional keyword arguments to the macro, while taking all other args into a list? Sth like this:
8:40:11
pve
I decided to see if Eclector could be used to provide a shorthand way of accessing instance slots. Here's what I got:
8:40:16
pve
https://github.com/pve1/eclector-access/blob/master/examples/slots-and-accessors-test.lisp
8:40:47
pve
I remember being a bit annoyed at the verbosity of accessing slots when I started lisping. I don't really feel that way anymore, but it was a nice exercise nonetheless.
8:41:44
lukego
Hey does anyone know the backstory on CLML? https://github.com/mmaul/clml. It's a machine learning library for Common Lisp that looks surprisingly (?) nice?
8:54:46
lukego
pve: I would totally use that if it can be added to an SBCL program without weird side effects like messing up debug info (I have no idea if that's a thing, just not sure how invasive switching readers is)
8:56:53
lukego
being a dweeb I would be tempted to introduce new unicode characters for backwards compatibility
8:58:15
lukego
seems like there's a lot of interest in using eclector in applications, and a lot of uncertainty about what the implications might be
9:00:45
lukego
I don't mean to be specific :) I am mostly just wondering if there are surprising consequences of switching the reader out or not. but okay SBCL has a lot of "source location" machinery for mapping machine code back to a path through the program e.g. to make 'v' work in the SLIME debugger
9:01:18
lukego
and I wonder if some of the machinery to make that work is in the standard SBCL reader and if so whether swapping it out would break stuff
9:02:46
pve
lukego: ok, but I should point out that in my example the reader is only changed on a per-file basis. So it is not an all-in situtation.
9:04:59
lukego
still, I'm looking at this imagining using it pervasively in all my application code :)
9:07:40
beach
lukego: Yes, I think source information will be lost since it is specific to the SBCL reader. Eclector uses a different (better) system called Concrete Syntax Tree, but that's optional, and incompatible with the SBCL evaluator.
9:09:47
beach
Of course, there is no longer any particular reason for a Common Lisp implementation to use an implementations-specific reader, so perhaps you can convince the SBCL maintainers to use Eclector instead. :)
9:11:43
pve
lukego: At least I'm able to jump to location from the debugger, and M-. to functions, so I don't know if much has changed.
9:11:44
beach
ACTION makes another futile attempt to cut the collective maintenance burden of maintainers of Common Lisp implementations.
9:15:10
lukego
beach: well you have people wanting your stuff now, it just might takes us a while to figure out how to use it :)
9:16:00
beach
lukego: Yes, that's a good start. Though, I insist that Eclector is no longer part of "my stuff". It is almost entirely the creation of scymtym.
9:17:40
pjb
greyrat: you cannot access the lexical scope with a macrolet as you envision. The problem is that macros are expanded at compilation-time, but your loop is evaluated at run-time.
9:20:13
greyrat
How do I loop on a list of lists? In the ith iteration, I want to have a list of all the ith elements.
9:22:13
beach
At the very least, we should try to convince the SBCL maintainers to allow the use of Eclector as an optional reader for things like COMPILE-FILE.
9:23:21
pjb
greyrat: if the number of lists is less than call-arguments-limit (minimum = 50) - 1 then: https://termbin.com/t8nd
9:24:31
greyrat
pjb: thanks. What if it's bigger than that? Should I iterate on the index itself manually?
9:25:37
pjb
greyrat: certainly not on the index, since that would automatically multiply the complexity by n!
9:26:49
pjb
greyrat: you can replace some by every if you want to stop on the shortest list, instead of the longuest. mapcar and the other map functions in CL stop on the shortest.
10:09:24
greyrat
Using sly, how do I see the stdout of the evaluation? `sly-eval-print-last-expression' inserts them in the current buffer, but I want to see them in a new buffer. (Of course, I can write my own wrapper around sly, just asking to see if there is already a ready solution.)
11:35:13
greyrat
I think i found the answer: (defun foo (mandatory &optional (optional1 nil optional1-supplied-p)) ...)
11:36:25
rotateq
if you don't need the predicate, then (defun foo (x &optional y) ...) is totally good
11:37:08
rotateq
but sometimes you want the intention when y stays being a list, so (defun foo (x &optional (y '())) ...)
11:40:51
rotateq
some days ago someone in #clojure said, in elisp the else clause for IF has implicit progn and concerned that a `cool feature` but it's not good at all and inconsistent
11:41:48
lisp123
rotateq: It may look strange but there's nothing bad about it, saves a user from having to write out the progn for it
11:44:29
lisp123
Well it saves the progn, its just that we are used to the symmetry on the CL side (which I think is better)
11:45:08
lisp123
After all RMS did write the GNU compiler so I don't want to throw stones at elisp too much :)
11:47:19
rotateq
and symmetry breaks might be good in nature and physics, to have some matter be left over
13:35:42
semz
pjb: Good point with the logging system. Keeping a bit of memory around specifically for these situations is starting to seem like the only real solution...
13:42:13
pve
lukego: It occurs to me that if we relax the readtable that "forwards" to eclector a bit, then jumping to location ("v") from the debugger will take me to the correct (nested) form.
13:42:37
pve
https://github.com/pve1/eclector-access/blob/master/examples/slots-and-accessors-test.lisp
13:51:19
pve
rotateq: the page for intersection says that EQL is the default, but set-difference says nothing, that's why I was wondering
13:52:48
rotateq
pve: and now more explicit what I asked myself, for what the heck :test-not was by hysterical raisin
13:54:26
yitzi
pve: I use it in common-lisp-jupyter if you are curious to do code inspection, code completion, code reading & compilation in clasp, and recreating source code maps for sbcl, cmucl, ecl and ccl.
13:55:11
specbot
Satisfying a Two-Argument Test: http://www.lispworks.com/reference/HyperSpec/Body/17_ba.htm
13:55:17
pve
I seem to remember that some page somewhere said that unless otherwise stated, a test defaults to eql, but I could have been dreaming
13:57:03
beach
rotateq: It is widely accepted these days that all those "deprecated" instances should be ignored.
13:58:38
rotateq
pve: And I had to recall that under EQL the comparing of two strings gives NIL, even if they have the same content.
13:59:48
beach
rotateq: Not always. The compiler can sometimes optimize so that two strings become one.
14:00:06
pve
yitzi: so you can read *everything* with eclector, and still jump to location works for nested expressions?
14:03:45
yitzi
pve: There are several areas where Eclector is being used and some parts where the implementation reader is used. I'll give you a basic explanation...
14:07:13
rotateq
Like using SCHAR rather than CHAR when it's clearly of type SIMPLE-STRING and the index given isn't out of bounds.
14:07:42
yitzi
pve: reading and evaluation uses the implementation's reader and compiler. Implementations vary on what they report as the "source code location" though. I need line and column references to make the debugger work. For clasp I use an enhanced gray-stream under their eclector reader. For SBCL, CMUCL, ECL and CCL I use eclector to recreate a map from the implementation's source references to line/column if needed. For code inspection/completion I
14:07:42
yitzi
use eclector with a custom client that does not intern symbols and keeps the package names separate so I can do inpection and completion on those also.
14:12:17
pjb
greyrat: I don't know about sly, but in slime, C-u prefix will make slime-eval-last-expression insert the result in the current buffer.
14:14:45
yitzi
pve: no problem. And yes, it is kind of mess but having a debugger in Jupyter makes it so.
14:16:29
pjb
rotateq: emacs lisp being to program emacs is not a reason why emacs couldn't include a full fleshed Common Lisp; ancien lisp machines contained several different lisps. and there is a Common Lisp implementation in emacs lisp that worked before (ironicallyh) lexical binding was introduced to emacs lisp (emacs-cl); lexical
14:17:13
pjb
this could be revived, or another CL implementation could be ported to emacs lisp; perhaps sicl? Or we could also integrate ecl as an emacs lisp plugin, now that they exist.
14:18:53
beach
pve: For the SICL reader, we do the same thing as yitzi with the Gray streams. We have Eclector configured to create concrete syntax trees, and that's what the first pass of the compiler accepts.
14:20:07
beach
pve: And for the purpose of bootstrapping, we may have to configure Eclector so that it does not intern symbols in the host package system.
14:23:12
yitzi
clasp does essentially the same thing and as a result writing REPL that preserved source references for Jupyter was very easy compared to the other implementations. Looking forward to SICL!
14:24:10
beach
You are already using parts of if, since Eclector is definitely a SICL-related project.
14:24:46
beach
I mean, it started life as the SICL reader, and was then extracted and greatly improved by scymtym.
14:27:53
yitzi
beach: Well, that is true. And trust me, that is a big deal because there is a lot of tasks in common-lisp-jupyter that would be very difficult without eclector.
14:29:17
beach
pve: For example, in SICL, the source information is a quadruple: start line, start column, end line, end column.
14:30:20
beach
Eclector queries the stream for source information. By default the FILE-POSITION is used, but with a Gray stream, the client can choose the format.
14:31:27
beach
Client code defines a Gray stream class, and method on the relevant Eclector method that queries for source information, specialized to that Gray stream class.
14:33:01
yitzi
pve: Eclector's source query is from the `eclector.base:source-position` method. You can see use of it here if you want. https://github.com/yitzchak/common-lisp-jupyter/blob/c5531f60da0ec288a187a55ba699e38548233819/src/cl-jupyter/utils.lisp#L224
14:33:21
beach
pve: https://github.com/robert-strandh/SICL/blob/master/Code/Source-tracking/stream.lisp
14:34:42
beach
Actually, SICL is even more special. It reads the entire file contents into memory first, and then characters are read from the memory representation.
14:35:31
beach
It does this so that the source code of the compilation unit is associated with the compiled code, in the form of a vector of strings.
14:36:09
beach
That way, the file can go away, and we still have source location in the backtrace inspector.
14:36:54
beach
Unlike SBCL, where the directory belonging to Krystof can not be found on my machine.