freenode/#lisp - IRC Chatlog
Search
4:22:45
beach
I guess in the spirit of the first example, I should have written (let ('5) (let (#'quote) (+ . #'6)))
4:25:47
no-defun-allowed
SLIME would print the lambda list of a mapping function I wrote as #'SEQUENCE.
4:59:09
beach
no-defun-allowed: That's a very good example of why I want something better than Emacs for writing Common Lisp code.
5:00:39
moon-child
that doesn't seem like a fundamental limitation of emacs though, only an incidental result of slime's implementation; no?
5:09:01
fiddlerwoaroof
It's fundamentally ambiguous whether the intention here is to print code or a list, as far as I can see
5:10:19
beach
One could, for example, show the characters in the source code that defined the item to be printed.
5:10:35
beach
Then you would get the same representation as the programmer wanted when the code was written.
5:11:42
fiddlerwoaroof
Yeah, that doesn't help when you're formatting the output of MACROEXPAND-1, though
5:12:47
fiddlerwoaroof
I use tools like emacs' macrostep expander quite a bit when I'm trying to figure out what a macro does
5:13:00
beach
Perhaps I am generalizing too much, but I almost never look at the result of a macro expansion.
5:13:48
beach
I see macros the say I see function, i.e., as abstractions. Only when I write the macro itself would I be interested in how it expands.
5:14:53
fiddlerwoaroof
When I decide that a macro was a bad idea, I usually MACROEXPAND-1 and replace the source with the expansion
5:15:39
beach
This is one reason why I made a rule that SICL macros should do a lot of syntax checking, so that conditions would be shown in terms of the macro call, rather than in terms of its expansion.
5:20:05
fiddlerwoaroof
I think if you continue down that route, you end up writing macros that expand to CLOS objects
5:23:00
beach
Not sure what you mean by "CLOS object", but if you mean "standard object" then that would be some very useless macros, since those are self-evaluating.
5:24:04
beach
... unless you implementation uses standard objects for conses and symbols, of course.
5:27:19
sm2n
beach, correct me if I'm wrong, but that kind of syntax checking doesn't compose too well
5:27:47
sm2n
i.e if I have a macro that expands into a macro, and the second macro has malformed syntax, the thrown error won't be in terms of the code I wrote
5:29:12
sm2n
and (+ . (quote 6) is exactly (+ quote 6), which has quote bound lexically to 5 by the let
5:29:25
beach
sm2n: Well, if the macro is meant to be used as an abstraction, it is usually clear what the different arguments stand for, so the syntax of those can then be checked. Perhaps not fully, but I am guessing a lot better than what is typically done.
5:34:55
sm2n
no matter how much syntax checking you have in bar, the error thrown won't be in (foo), because macroexpansion destroys that context
5:36:49
beach
Ah, yes, I see. That's the reason for another SICL rule, namely to report errors in terms of source expressions in context.
5:38:09
beach
But your scenario is definitely not the one I was thinking of. In this case, my scenario would be the time when the macro FOO was written.
5:39:07
sm2n
I don't really think it's much of an issue because CL isn't conventionally written with deeply nested macros from what I can tell
5:39:20
beach
There would be some highlight of the (BAR BAZ) expression with an indication that the number of arguments is wrong.
5:40:17
sm2n
I brought this up because this was the motivation for the racket people to move to syntax objects as the result of macroexpansion, which is close to what fiddlerwoaroof was implying by macroexpanding into CLOS objects
5:40:54
fiddlerwoaroof
If you have mid-level macros that expand to standard objects, and high-level macros that expand the standard objects to conses, you can preserve all sorts of metadata
5:42:01
beach
fiddlerwoaroof: I think I see what you mean now. Not that the expansion itself is a standard object, but something like (FOO <standard-object>). Yes?
5:42:41
fiddlerwoaroof
Or, (foo (bar)) and then bar expands to (foo #<standard-object>), which foo expands itself
5:43:58
fiddlerwoaroof
I think reading your paper on SICL loop was the first time I thought of this idea
5:45:26
no-defun-allowed
I think I was approaching something like that this morning to simplify code generation for a new project. It would use vectorised loads, stores and comparison operators, but my compiler would generate something like (load #<some policy representation> vector n), which would then be expanded using a generic function that the client would specialize.
5:45:26
beach
I never thought about generalizing it to more mundane macros though. Food for thought. Thanks!
5:47:10
no-defun-allowed
It's still very fuzzy though, and I've only written down a summary of the protocol for the rest of the project so far.
5:49:30
moon-child
(aside: the above discussion of macros and abstraction makes me think that sigils are superior to namespaces. Imagine we use & for function values, % for macros and builtins, and $ for variables. Then the 'quote' symbol used by the ' reader macro cannot possibly collide with a local variable which is also named quote)
5:52:53
no-defun-allowed
(The end goal is to make my regular expression compiler more modular, and allow the client to generate specialised scanning code, based on CPU features and/or any specific knowledge of the text to match.)
6:00:15
fiddlerwoaroof
no-defun-allowed: if you need complex regular expressions to benchmark, this code here generates some amazing regular expressions: https://gitlab.common-lisp.net/rfc2822/rfc2822/blob/master/regex.lisp#L118
6:01:44
fiddlerwoaroof
I tried printing one out once to see why CL-PPCRE was taking so long to match something like "foo" <foo@bar.com>
6:06:16
beach
fiddlerwoaroof: In Cleavir, we get some of the benefits of using standard objects in macros, in that the compiler manipulates CSTs rather than expressions, and after macro expansion, it reconstructs a CST from the original one and the expression returned by the macro expander.
6:08:59
fiddlerwoaroof
It's occasionally seemed to me that the distinction between a compiler and a macroexpander is sort of arbitrary
6:11:24
fiddlerwoaroof
They're both programs that take a datastructure that represents a program in one way and turn it into a datastructure that represents the same program in a different way.
6:12:58
Nilby
If I'm remembering correctly I think agnostic-lizard uses a technique something like that, wrapping interim macro expansion in objects.
6:13:11
fiddlerwoaroof
One interest I've had is trying to pull some of the traditional compiler stuff into the macroexpansion phase, because that phase has always seemed easier to think about (to me)
6:14:43
beach
Yeah, that's a good idea, provided that errors and warnings can still be meaningful to the programmer.
6:14:46
fiddlerwoaroof
Nilby: I believe I remember seeing something like that in the presentation on that tool
6:48:17
no-defun-allowed
I use the derivative method, so I can do intersections on regular expressions.
6:49:25
fiddlerwoaroof
Basically, I've had this sort of problem before: I have N regex-action pairs (think awk-style programs, or HTTP routing) and I want to pick an action doing as little work matching as possible
6:50:14
fiddlerwoaroof
I think the derivative-style matching would work for this, now that I think about it
6:51:01
no-defun-allowed
After testing, I can only conclude that submatching here is painfully broken.
6:58:09
contrapunctus
Would you folks recommend using Clostrum for sandboxing Lisp programs? Or is there another way? It seems like a complicated problem.
6:58:51
Shinmera
the only way is to either restrict the programs to the point of being useless, or running another process.
7:00:44
fiddlerwoaroof
In theory, you could spawn another process and use the cgroups APIs to sandbox it
7:05:23
contrapunctus
fiddlerwoaroof: to be specific, I don't want the program to (unless the user permits them) make any network requests or access the filesystem outside of its private storage. (There's also some resource limiting.)
7:05:38
beach
contrapunctus: To get the benefits of Clostrum, you need to be able to evaluate expressions "relative to" a Clostrum environment, so you need a specific evaluator.
7:06:10
beach
contrapunctus: We have such an evaluator (obviously), but things are not set up for general use. Currently, it is used only in SICL bootstrapping.
7:07:15
beach
contrapunctus: The existing evaluator turns a source file into a CST (using Eclector), and then the CST into an AST (using Cleavir) and then it uses the AST evaluator of SICL that does the job.
7:08:10
beach
One day, I may turn these tools into something generally usable, but I don't have the time to do that now. Perhaps someone else would be interested in such a project.
7:28:54
no-defun-allowed
As with most of the engine, I have no idea what I did exactly, but submatching appears to work properly now.
7:32:39
contrapunctus
beach: I see. I feel quite sad when I think of how, on one hand, it's desirable to have programs in e.g. documents, and yet the state of sandboxing and resource limiting leaves much to be desired.
7:35:08
beach
contrapunctus: I understand. I wish someone would take on the project I suggested. What you would like to see is something many people seem to want.
9:33:55
ikrabbe
I often try to write macros that call functions from their arguments: (defmacro mac (x) `(,x y))
9:35:10
ikrabbe
I can guard this call with fboundp of course (defmacro mac (x) `(if (fboundp ',x) (,x y))
9:36:23
ikrabbe
) but this only works for defun'ed objects, not for (labels ((x () )))) (does it work for (lambdas?))
9:37:54
no-defun-allowed
In the case of the MAC you wrote, the implementation will usually signal a WARNING at compile-time if the function is not bound, so you shouldn't have to worry about it.
9:38:57
no-defun-allowed
Though I wonder if there is something you can do with the CLtL2 environment introspection extension which many implementations provide (given that FBOUNDP does not take an environment argument, but you can get an environment with that information from a macro).
9:44:38
no-defun-allowed
ikrabbe: This implementation of MAC generates (redundant) warnings for unbound function names: https://plaster.tymoon.eu/view/2381
9:47:15
no-defun-allowed
That might only work on SBCL, but I found a trivial-cltl2 system on Quicklisp which should be more portable.
9:47:19
edgar-rft
A macro-lambda-list has an optional &environment parameter to look-up lexically bound functtions (flet, labels, etc.) but I have no clue how that works.
9:59:04
ikrabbe
no-defun-allowed: What I actually miss is a branch for cond, when I parse such arguments: (say "Good morning" (user 10))
9:59:56
ikrabbe
(defmacro say (&rest x) (mapcar (lambda (o) (typecase o (sequence (if t `(,(car o) ,@(cdr o))) (print o)) (t (print o)))) x))
10:01:05
ikrabbe
This is an error of course, as "Good morning" is a sequence also. I need a cond statement if (car o) is callable.
10:02:33
no-defun-allowed
Would you not want to test for the LIST type instead of SEQUENCE? And then I suppose (equal `(,(car o) ,@(cdr o)) o)
10:08:21
ikrabbe
no-defun-allowed: list or sequence, the problem of the sequence can easily be overcome by deciding on strings before. My problem is still the missing condition.
10:15:42
no-defun-allowed
Are you trying to print at macroexpansion time? Local functions will not exist at compile time and cannot be called.
10:36:10
ikrabbe
no, that was just too short, but I begin to understand, that I should define all callable functions for a macro expansion.
10:37:00
edgar-rft
I just was going to say "why does that thing to be a macro at all when a function will do the same".
10:44:27
ikrabbe
it does not need to be a macro. But then I need to call it as (say '("Good morning" (user 10)))
10:55:14
edgar-rft
It was not meant as a negative critic, I only wanted to know if there is some reason that I can't see from the example code. Writing macros needs to care a lot more about corner cases than writing functions, as you already found out youself :-)
10:57:47
no-defun-allowed
Does it? You could write (defun say (&rest r) (mapcar #'print r)) to get (say "Good morning" (user 10)) to print "Good morning" then the result of (user 10)
11:07:04
ikrabbe
no-defun-allowed: actually print is just the test application. Depending on the situation I want (user 10) to be evaluated later. For the terminal it might be (print (user 10)), or in clim it could be (write-string (user 10)) or (present (user 10) 'username)
11:08:23
ikrabbe
when i do (defun say (&rest r)) the evaluation of (user 10) will likely be a string, but I lost the information that it is a user
11:30:12
mmontone
Hello. Does anyone know if there's a way of getting the list of packages loaded by a particular ASDF system?
11:31:28
ikrabbe
lotuseater: I could do many things, but I want to decide what to do, when I know anything about the output medium. When I write such a say statement in a html context, I might want to link to a user account... and user is just a simple example of what is possible
11:37:54
Xach
mmontone: i don't believe there is any easy way. a system may cause other systems to load that define more and more packages that aren't directly loaded by that system.
11:38:20
Xach
mmontone: but you could look at interceding at certain points and comparing snapshots of (list-all-packages)
11:40:27
mmontone
I thought perhaps there was some trick, like parsing ASDF system and files, or perhaps from swank information, but I don't think there's something. And I need it to be fast and lightweight, I don't want to trigger some file system processing or something like that, because I'm trying to implement an on-line documentation tool.
11:42:01
Xach
mmontone: i don't think there is any way aside from loading the asdf system and looking at the state of the package system.
11:43:46
mmontone
Yes..probably not possible. I was just asking just in case. Thanks for the input Xach.
11:47:01
Xach
mmontone: another option is to look at the xref data for packages, and see if the source file is in a particular known system
11:58:06
mmontone
https://drive.google.com/file/d/17uGr0B1OVc6nX9f73p3Hhqn5jRSx6bY8/view?usp=sharing
12:01:05
mmontone
Occurred to me when I was using slime completion to see what some package provided, and I couldn't see much from there, docstrings, etc. So I thought that was not the right way, there could be better ...