freenode/#lisp - IRC Chatlog
Search
17:42:01
Bike
"Classes defined by defclass in the compilation environment must be defined at run time to have the same superclasses and same metaclass." is the text
17:42:41
jasom
So it would require a separate declaration that indicates the class would not be redefined.
17:47:39
beach
jasom: But one can play the same kind of tricks as one can with an accessor, provided the slot name is constant.
17:48:44
beach
jasom: But things may have to be recompiled when the class changes, just like the accessors do. That can be done of course.
18:25:07
makomo
for example, if i have (macro-function 'alexandria:once-only), how do i funcall this properly?
18:25:22
makomo
the bottom of this page says that the first argument is the "entire macro call" http://www.lispworks.com/documentation/HyperSpec/Body/f_macro_.htm
18:26:13
makomo
is this correct (funcall (macro-function 'alexandria:once-only) '((x) ((print "hello there"))))?
18:28:00
Bike
and the second argument is an environment. just pass NIL, to indicate the global environment
18:28:31
makomo
Bike: can you clarify what is the "whole form"? literally (once-only (x) (print "hello there"))?
18:28:41
pjb
(funcall (macro-function 'alexandria:once-only) '(alexandria:once-only (x) (print x)) nil) #| --> (let ((#1=#:once-only175411 (gensym "X"))) (list* 'let (list* (list (list* #1# (list x))) (list (let ((x #1#)) (print x)))))) |#
18:29:30
pjb
eg. when you define macros to expand to HTML, it's always the same thing. You can have a single macro function for all!
18:29:41
Bike
macro functions taking different arguments depending on the macro lambda list would be confusing for no reason.
18:30:17
makomo
pjb: hm, interesting but i don't get the example. single macro function for all what?
18:31:05
Bike
like have each html tag bound to the same macro functio, which checks the first element to see what to do.
18:32:59
pjb
(defun gen-html-tag (form environment) (destructuring-bind (tag &rest body) form `(progn (format t "<~A>" ',tag) ,@body (format t "</~A>" ',tag)))) (setf (macro-function 'a) (function gen-html-tag) (macro-function 'p) (function gen-html-tag) #| …the whole html…|#) (with-output-to-string (*standard-output*) (p (princ "foo") (a (princ "link")) (princ "bar"))) #| --> "<p>foo<a>link</a>bar</p>" |#
18:34:10
pjb
Now, for html, it's a tad more complex, since there are sometimes optional open or close tag, and various set of attributes, etc. so you'd need more than one function, but, it this could still be used.
18:39:14
pjb
If you want to call this function from within a macro, you should (defmacro m (… &environment environment) … (gen-html-tag form environment) …)
18:40:07
pjb
now, notice that the above function didn't use the environment, but if it called macroexpand, it would have to pass it.
18:40:49
pjb
Notably, macroexpand let you detect or process symbol-macros (not only normal macros), and you would see symbol-macrolets, only by using this environment.
18:45:40
makomo
welp, that concludes my macro-function solution and it's no better than what i had before
18:47:48
pjb
makomo: for a macro, you cannot just "evaluate" something. You have to make it explicit if it is evaluated at macroexpansion time, or if you return a form that will evaluate it at run-time.
18:48:52
pjb
Then it is possible, but difficult. Since this evaluation is done, eg. in the compilation environment, it cannot rely on anything defined in the program.
18:50:34
makomo
pjb: right, and the context is this: we were discussing how to solve the multiple evaluation problem when you don't know the number of symbols "at compile-time" (???)
18:50:50
pjb
makomo: but as I said, you only need to add a macro. Ie. instead of evaluating initforms in the once-only-list macro, evaluate it at macro expansion time in a macro that expands to once-only-list (or whatever).
18:50:59
makomo
not sure if that's the right terminology, but i hope you get what i mean -- you can't tell ONCE-ONLY to do it for a list of symbols
18:52:33
Bike
i don't understand how this works. in fbind-2, is (mapcar #'second bindings) evaluated when once-only-list-eval is macroexpanded?
18:52:57
makomo
the point is to reuse ONCE-ONLY, instead of having to write a function (or rely on the authors to do so) that will return me the expansion of ONCE-ONLY
18:54:29
Bike
so it's not evaluated when once-only list-eval is expanded. it's evaluated by its expansion.
18:56:13
makomo
Bike: erm, yeah, but the FBIND macro itself is also expanded at compile-time, and it contains the expansion of ONCE-ONLY-EVAL-LIST
19:01:08
makomo
Bike: yeah, true, it's non-trivial, but it's interesting to see the same patterns pop up when writing macros
19:04:14
pjb
makomo: perhaps you could use once-only. But the thing is that you must evaluate your expressions in the right macro. The parameters to a macro aren't evaluated by the called macro, so you need to compute them in the caller!
19:04:41
pjb
Hence the let that computes names, initforms, and funs in fbind, not in an once-only-list.
19:05:07
makomo
pjb: that happens in my FBIND too, it's just that ONCE-ONLY-LIST expands into code that does that
19:10:22
makomo
Bike: also, you would probably use ONCE-ONLY if you didn't have an arbitrary number of bindings
19:10:34
makomo
because that's the point of ONCE-ONLY, to help you write macros and reduce boilerplate when writing them
19:12:40
pjb
Again, I drop it, there's no need to implement something like once-only-list, or to use once-only. It only makes the macros more complicated than they should be.
19:15:08
pjb
perhaps. On the other hand, I like to use different names for the expression and the variable bound to the expression. (let ((,vstuff ,stuff)) …) instead of (once-only (stuff) …).
19:15:12
Bike
wow, and fbind itself expands into something easy to understand, despite its horrible upbringing
19:16:14
makomo
whatever form is bound to STUFF within the macro is evaluated once within the expansion into a gensym, which is bound to HELLO within the macro
19:16:15
pjb
In macros, it's important to keep separate the bindings in the different environments, or levels of backquotes. Once-only confuses things up, IMO.
19:16:55
makomo
meh, idk, i don't feel like it's that confusing. it's just a thing that you get used to, just another "black box" if you will
19:21:59
Xach
Friends, this day we will have a new Quicklisp dist update! I can feel it in my bones!
19:24:00
Bike
but you could try removing it, and then rewriting fbind to do (once-only-list (funs (mapcar #'second bindings)) ...),and then macroexpand it
19:25:37
Bike
i friggin hate writing code like this. i have to reverse engineer what i wrote thirty seconds after writing it because it doesn't stay in my head
19:25:57
makomo
Bike: ah you're right, but it doesn't have the same function as the ONCE-ONLY i used within my expansions
19:26:16
makomo
this is only for the purposes of your own macro's hygiene, it has nothing to do with the ultimate goal, i.e. reusing ONCE-ONLY
19:28:05
makomo
but once it is written, you can forget about it and use it like a black box, so who cares how complex it is underneath if it's well documented and does it job
19:28:41
Bike
yes, i'm doing it "manually", because like i said, once-only and once-only-list are not the same thing.
19:29:36
makomo
one takes a list of a constant number of specs, the other takes an arbitrary number of specs
19:32:57
_death
I think macros are for syntactic convenience and clarity, and this "re-use" inverts the purpose ;)
19:33:45
makomo
otherwise you can't escape from constantly rewriting the same things over and over again, such as avoiding multiple evaluation
19:33:57
makomo
(in the case of an arbitarary number of forms, that is; otherwise you just use ONCE-ONLY)
19:34:29
_death
also, once-only rebinds the names passed to it.. in this situation I don't think you need that
19:35:07
makomo
_death: right, but those disappear in the end anyway because nobody uses those rebound symbols
19:35:47
makomo
literally anything that you want to generalize to an arbitary number of arguments is screwed
19:38:24
makomo
so in the end, the only solutions are (1) use the original macro and EVAL to make it work for an arbitrary number of arguments or (2) write two versions of the same macro
19:42:20
_death
the fact that you call gensym by yourself already indicates an issue.. after all once-only is supposed to hide the use of gensyms
19:43:19
makomo
these are the symbols that then get rebound, but nobody cares about them anyway, because nobody knows their names and what initforms they correspond to
19:43:33
makomo
we care about the gensyms made by ONCE-ONLY, those that are part of the expansion that ONCE-ONLY helped write
19:44:11
makomo
this isn't something the user does, this is just to actually implement the list version of ONCE-ONLY
19:45:47
makomo
and EVAL wouldn't even be a problem if i didn't have to explictily pass variables of the using macro to ONCE-ONLY-LIST so that they're available in the EVAL
19:46:06
_death
if you look at your final fbind macro, it looks pretty similar to the fbind that uses a function that returns the gensyms and the bindings
19:48:35
_death
https://plaster.tymoon.eu/view/842 ;; remove the silly gensym->name that was there to make a point
19:49:40
makomo
right, but i don't see how that's a bad thing. it's not something you can avoid either, since there's an arbitrary number of symbols you have to create
19:51:55
makomo
the call to this function and then binding its results and using them to prefix my own macro with a LET
19:53:33
_death
and still you can have a once-only-list macro that doesn't use once-only and it should be much simpler
19:54:16
makomo
although it then requires that the author plan ahead for the arbitrary version right away, instead of the constant version
19:55:11
makomo
hmm. yeah, the arbitrary one evaluates at macroexpansion time so maybe that's why it appears to be different?
19:58:52
auricle
hello fellows, I have not found a GLL parsing library for CL so I am going to translate one from this Racket GLL library: https://github.com/epsil/gll/blob/master/3/parser.rkt
20:00:39
makomo
_death: huh... i don't think the constant version can be written using the arbitrary version... without EVAL
20:20:26
pjb
makomo: in scheme eval takes an environment argument (like macroexpand or the macro functions). This is what makes it actually rather useless! You don't usually have the environment you want to evaluate things…
21:01:04
auricle
Xach: so one can finally just write literally the BNF grammar one wants without having to factor it at all, like a human being
21:02:43
auricle
Xach: that seems liek a beefed up regex library. I think GLLs are like beefed up PEGs (they can parse CFGs)
21:03:58
auricle
Xach: by that I meant being able to write "expr -> expr + expr" whereas that would never work in most parsers... you'd need to factor it out; not so with GLLs
21:06:10
auricle
Xach: have you ever translated a library from scheme that I could use as a reference for all the tricky "..." (scheme's macro ellipses) etc?
21:25:36
auricle
Xach: in case you're interested there's apparently a so-called "Earley algorithm" that gives us PEGs with left-recursion. anyway, I'm out, have a good day, and thanks for all you do for CL
23:52:38
didi
Is anyone aware of an expression language for defining dates? Like CL-PPCRE accepts a parse tree for defining regular expressions.
0:27:12
pierpa
check out Calendrical Calculations, and use whatever they use (and their software is written in CL, and is available from the publisher website, although with a weird license)
1:36:46
sjl_
defining an after method on initialize-instance is a pretty common idiom. I don't know that I've seen it done on make-instance very much.
1:36:59
skidd0
when I make an instance of a list, i want to auto add that list to a .. list of lists..
1:38:31
skidd0
I have an interactive function that prompts the user for info (like name, tags, about) and then pushes the new list onto a special var *task-lists*
1:40:38
Xach
skidd0: i think i would not do it that way, because it can be nice to make objects without causing a side-effect like that, e.g. when you're just testing things out.
1:43:19
skidd0
but it's worth noting that I always want the task-lists to be added to the list of task-lists
1:44:03
Bike
for testing i've pretty much never regretted being able to make a thing without side effects
1:49:15
skidd0
with make-task, i'm thinking that's basically taking the init args and then using them in a make-instance
1:51:26
Zhivago
Isn't this just a matter of creating a constructor function which also adds the thing it constructs to a list somewhere?
1:54:29
White_Flame
but once you have automatic behavior, then you want to make it optional, you need to have side-band ways of passing in options to that automatic behavior
1:55:06
skidd0
and then, i'll have a really complex way to make lists, and have spent a while learning how to do that, and still not have tasks
1:56:36
White_Flame
btw, (defun maker (&rest params) (let ((obj (apply #'raw-maker params))) ...)) is how you pass through parameters
1:57:05
Zhivago
Probably your problem involves 'making a data structure for some particular purpose', and that just happens to involve lists today.
3:01:54
cnx
hi there, somehow i can no longer load swank server due to `Package ASDF does not exist.'
3:27:40
White_Flame
it's always best to install SBCL from source, instead of from your package manager, due to weird issues like this
3:38:39
White_Flame
if you start SBCL from the commandline and type (require :asdf), what do you get?
3:43:29
White_Flame
it shouldn't just "break", so I would suspect something external in the environment
4:01:26
makomo
phoe: did you take a look at the macros i wrote (regarding the FBIND thing we discussed) :D?
4:09:04
White_Flame
cnx: REQUIRE is a deprecated, implementation-specific thing that's usually only used for implementation built-ins
4:10:07
White_Flame
asdf:*central-registry* is the list of directories it looks for .asd files to load
4:10:27
White_Flame
quicklisp also has a couple for the quicklisp distributions as well as local-projects
4:30:28
White_Flame
cnx: because you asked for asdf:*central-registry*, that means that that symbol was defined in the package, aka it loaded
4:30:58
White_Flame
NIL means the value was defined. It would have blown up with an error if neither that package nor symbol existed
4:38:28
cnx
I'm feeling kinda sick now, I guess I'll try to get more sleep and debug this later, thanks White_Flame