freenode/#lisp - IRC Chatlog
Search
15:01:53
jackdaniel
most likely scenario is that you had quicklisp initialized in your implementation init file (i.e ~/.sbclrc) and you have removed it
15:09:36
theseb
is this a great macro strategy?....do as much as you can with a "normal" function and then call that helper function from your shiny new macro?....in short..use macros to change the syntax of the language but do the real work in regular code?
15:12:01
theseb
beach: thanks...people were always warning about overdoing it with macros...my strategy above seemed like such a simple way to strike a balance...it should be more widely taught
15:12:47
beach
theseb: It's the traditional way of doing it, but perhaps it is not said so explicitly in the literature.
15:14:59
beach
But if you look in the CLIM II specification, for instance, you will find several pairs like WITH-FOO and INVOKE-WITH-FOO.
15:18:16
theseb
Xach: everyone knows Common Lisp is the Lisp for "real work"...however...I've been checking out Clojure which seem to also be good for "real work" since uses JVM...what do think of Clojure?
15:19:38
jmercouris
Isn't it possible to run CL on the JVM? I thought there was an implementation that had interop of some sort
15:22:43
figurelisp
I have heard a lot about lisp. Is it good to learn it now? I am thinking about common lisp
15:23:33
francogrex
hi, I have a lisp (or fasl) file in a specific common network directory/folder (UNC path: //network1/specs/called.fasl) that is being loaded from a user's local lisp program. is there a way to make sure that the user is loading that specific fasl file (and not a local one he may have copied into his local folder?)
15:24:45
figurelisp
I'm new in programming so i don't know other languages well and won't be able ito compare it
15:25:06
Josh_2
well I learned CL first and now I don't want to learn any others cos I'm lazy and they suck
15:26:26
jmercouris
Anyways, these kinds of debates are pointless, if you wish to learn Lisp, obviously you'd have the endorsement of this channel
15:27:48
jackdaniel
any argument supporting my ideas is valid. contrary arguments are just other people delusions (and false claims), like it ought to be ;-)
15:28:00
jmercouris
figurelisp: If you decide to learn lisp start with this book: https://www.cs.cmu.edu/~dst/LispBook/book.pdf and install this editor: https://portacle.github.io
15:28:01
Josh_2
figurelisp: get gentle introduction to symbolic computation, is very good intro to programming :)
15:28:01
figurelisp
I'll be starting learning CL from the book cl: gentle introduction to symbolic computimg
15:29:14
jackdaniel
jmercouris: confirmation bias won't do any good to you. Lisp zealotry just closes you in a fixed mindset.
15:30:14
jackdaniel
usually jokes carry convictions despite being humorous, but tha'ts offtopic on my side, sorry
15:31:21
beach
figurelisp: Make sure you ask for advice when you get ready to install your environment. It is easy to get it wrong.
15:32:36
beach
figurelisp: Also, it is OK, to paste your code somewhere and give us a link, in case you want feedback on it. Newbie questions are tolerated as long as it looks like you are making progress and following advice.
15:46:56
schweers
figurelisp: my advice: don’t let people tell you that the lisp you chose (Common Lisp, as I understand) has some flaw, and that another lisp is better. Or at least in some way better. Its not that they are wrong (if you really want to do functional programming, Clojure has a more pleasant out of the box experience). Its that you shouldn’t let that distract you. I made that mistake, bouncing from one lisp to anothe
15:47:46
Josh_2
schweers: idk if I agree with you, GISC is a real good intro to functional programming
15:52:17
jmercouris
When writing predicates, when do you use a hyphen, and when do you just stick it onto the word?
15:52:43
schweers
jmercouris: I think most people use a dash if the predicate consists of more than one word
15:56:29
random-nick
is the proper naming convention for definition macros to prefix with "def" if it is just one word and to use dashes and prefix it with "define-" for multiple words?
15:58:45
Xach
concluding with: The name string-less-p would incorrectly imply that it is a predicate that tests for a kind of object called a string-less, and the name stringlessp would connote a predicate that tests whether something has no strings (is "stringless")!
16:09:41
jmercouris
If I use (with-slots) within a method body, is it any quicker than using the slot accessors every time?
16:15:16
makomo
jmercouris: i'm not sure if this is correct (someone can correct me), but i would think it could be slower because it has the extra dispatch to go through for the accessor
16:16:56
makomo
jmercouris: also, WITH-ACCESSORS supports any accessor and doesn't have to be used just for objects/slots
16:17:20
beach
jmercouris: WITH-SLOTS uses SLOT-VALUE. SLOT-VALUE takes a symbol to name the slot. If the implementers are not careful, they have to look up the name, find the slot metaobject, find the slot offset, then access the slot.
16:18:40
makomo
beach: we discussed this once -- the fact that WITH-ACCESSORS doesn't have to be used just for slots. is this true or is my memory just failing?
16:18:48
jmercouris
I feel like maybe the only way to really learn this stuff is to make your own CL implementation of the spec
16:21:32
beach
Look at the bottom of the Common Lisp HyperSpec page. It says what with-accessors does.
16:22:10
makomo
for some reason i thought you were limited to instanced of classes that are DEFCLASS'd
16:23:13
makomo
it's not complicated. maybe it's just because you've only heard about it for the first time
16:23:52
jmercouris
makomo: I don't know, I just have these vague ideas in my mind, it would seem to me that with-slots is kind of like some version of let, so you don't have to keep getting the value every time
16:26:07
makomo
jmercouris: ah, well, it could have been made to do that instead i guess. it's all about the documentation and standardized stuff in the end :D
16:27:35
beach
jmercouris: And, in the worst case, it must find the class of the object (another function call), then find the slot metaobject with that name (another call), then access that object to find the slot offset (another call), then access memory (another call).
16:28:05
makomo
jmercouris: heh, that's how i felt while implementing this macro: https://plaster.tymoon.eu/view/844#844. now i finally feel like the idea has crystallized
16:28:14
beach
jmercouris: There are tricks to get around it when the slot name is quoted, but it is not simple to implement.
16:58:15
jasom
beach: can you declare the type of an object in such a way to remove some of those lookups (with declarations in the standard)?
17:00:49
Bike
strictly speaking, the compilation semantics allow you not to worry about that, i think
17:01:41
Bike
that is, there's no restriction that the slots of a class have to be the same at compile and run time
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.