freenode/#lisp - IRC Chatlog
Search
22:15:26
frodef
I fell silly for asking this, but what is the preferred idiom for taking the subset of a list by some predicate?
22:17:31
frodef
yes, but remove-if-not and the :test-not args are "deprecated", which makes me suspect there's supposed to be another way...
22:18:15
Bike
it was deprecated like twenty years ago because they thought COMPLEMENT would be more useful.
22:18:53
Bike
but there is no problem using remove-if-not and even if there was somehow a new standard revision, they probably wouldn't actually remove it.
22:29:20
mfiano
It's surprisingly actually smaller code size on SBCL, too (though code zie is not a good measure of performance).
22:54:36
frodef
Bike: right, thanks, COMPLEMENT was probably the piece of the puzzle I'd forgotten about.
22:57:04
frodef
...and even more so for (remove keep-value ... :test-not 'eql), which is not very readable at all.
23:00:57
frodef
-- "Several alternative names for REMOVE-IF-NOT were suggested: KEEP-IF, ABSTRACT, FILTER. We did not pursue these suggestions." Oh well.
0:07:53
aeth
a true IF-NOT in the language would have a second branch and just reverse the order of the IF
2:12:35
dbotton
if anyone over next day or so has time and can try out my tutorial 8 from CLOG running at http://office.botton.com:8080/ I made some critical changes from last test (thank you for using it those that did). The source is at https://github.com/rabbibotton/clog/blob/main/tutorial/08-tutorial.lisp
2:14:13
brandflake11
Hey all, I have a question for you all. I am writing a function in lisp, and need to create a list out of the function's arguments. Here is what I have for the function:
2:14:56
Bike
please use a pastebin service for multi-line pastes. anyway, so this function is supposed to randomly select and return one of its three arguments?
2:15:40
Bike
The only problem I see in this paste is that you meant to write (list note1 note2 note3).
2:17:07
Bike
you wrote (note1 note2 note3). this means it will call the function NOTE1 with two arguments. Since there's no function called NOTE1, you get an error.
2:17:45
Bike
your compiler might alert you to this. SBCL says "Undefined function: NOTE1" when you compile, and "The function NOTE1 is undefined" when you actually call it.
2:19:11
Bike
No, but if you all you want to do is pick one of the arguments randomly, you probably don't need to make a list.
2:19:13
brandflake11
I tried '(note1 note2 note3), but they gave me the literal variable names as members in the list
2:23:24
brandflake11
Does the &rest args stand for something? Like is it an abbreviation of a phrase in English?
2:40:30
brandflake11
One more question: can you use &rest with other mandatory variables? Like (note1 note2 &rest args) making note1 and note2 arguments mandatory?
2:43:22
fiddlerwoaroof
If you know you have 3 arguments, something like this is probably better: (define pick-three (a b c) (ecase (random 3) (0 a) (1 b) (2 c)))
2:54:12
saturn2
you could also get the best of both by adding (define-compiler-macro pick-random (&rest args) `(ecase (random ,(length args)) ,@(loop for arg in args for i from 0 collect (list i arg))))
2:57:17
saturn2
that macro writes code like what fiddlerwoaroof wrote, but for any number of arguments
2:59:38
saturn2
they are functions that return lisp code, which is then inserted in place of the macro call
2:59:57
brandflake11
saturn2: I haven't learned about macros yet either. But man, that is really cool.
3:03:55
saturn2
and of course you can have regular loops in your macro, the one i wrote above has one
3:07:05
aeth
brandflake11: So with quote, it basically follows the distributive property. '(a b c) is essentially like (list 'a 'b 'c) just like (* z (+ x y)) is like (+ (* z x) (* z y))
3:07:27
aeth
Quasiquote is a quote you can unquote. `(a b c) is essentially the same as '(a b c) because there's nothing to unquote so it's just all quoted.
3:07:49
aeth
`(a ,b c) however, will "unquote" b and so it's like (list 'a b 'c) instead of like (list 'a 'b 'c)
3:09:05
aeth
,@ is a bit more complicated. It's unquote splicing. It basically appends the inner list into the outer list
3:10:58
aeth
As for why you'd need ,@ it's mostly for targeting some macros like LOOP, e.g. (loop repeat 3 do (print "hi"))
3:11:49
aeth
If you're writing a macro with quasiquote that generates a loop, you'll probably have to do something like this: (loop ,@(generate-the-clause-here) do (print "hi"))
3:12:09
brandflake11
saturn2: That makes sense, since you don't want separate lists together. You want one lits
3:12:59
aeth
The other time you see ,@ a lot is with `(progn ,@body) in macros that have an &body body which is essentially just giving you the rest as a list just like &rest rest
3:15:44
aeth
The defmacro for WHEN might look something like this (name changed so you can evaluate it): (defmacro when* (test &body forms) `(if ,test (progn ,@forms) nil))
3:18:33
aeth
If a function is (defined in another file that's loaded first) or (wrapped in an EVAL-WHEN) then it can be used as a helper function... at least for macros; I've never really had to use compiler macros.
3:20:33
brandflake11
Is a helper function one that is previously defined to be used in another function?
3:21:33
aeth
I personally see it as a function that's designed to keep another function (or a macro) short/simple/easy even if it's only going to be called from one caller (at least, outside of unit tests)
3:22:30
aeth
A lot of people don't like functions that are only called from one place, but I love them, especially in macros.
3:22:45
aeth
As for unit tests, those are tests of a unit... usually a function or a class or things like that afaik.
3:23:18
aeth
If you break up a big, messy macro into lots of functions, then you can test to make sure that any changes you make don't change any of those functions, which gives you more confidence to mess around with really tricky macros
3:24:15
aeth
If you just have the macro, then you'll have to write a lot of tests on the macro directly, probably with MACROEXPAND-1 to test expanding the macro
3:27:16
aeth
More concreately, you could have a function for your macro that turns (foo bar baz) into ((foo (make-quux 'foo)) (bar (make-quux 'bar)) (baz (make-quux 'baz))) and this is small, simple, and easy to test.
3:28:48
brandflake11
aeth: Have you had to change the way you format your macros in professional environments because some people don't like formatting like that?
3:30:20
aeth
Try to match the style of the person who originally wrote the file. There are lots of little things that can be different in styles.
3:39:03
brandflake11
Thanks to all of the help I received on here. I have created my random sequencer in common music successfully!
4:30:08
beach
FILTER is not a great name for a filtering function, because it doesn't say whether the objects for which the predicate returns true are kept or discarded. REMOVE-IF and REMOVE-IF-NOT are much better.
4:43:50
beach
Dizidentu: So I saw in the logs that you are a C++ programmer. I think it would be a good idea for you to learn some Common Lisp to get another perspective on programming.
5:56:21
beach
Python is a pure interpreter, which means you can't really get any performance out of it, unless you write your code in C.
5:56:44
beach
Most Common Lisp systems compile on the fly, so you can write all your code in a truly high-level language.
5:57:21
beach
Furthermore, Python is not homoiconic, so you can't really do any metaprogramming in it, like macros.
5:57:50
White_Flame
each languages seems to have its own definition of "metaprogramming". For python, it seems to be adding hooks on object methods
5:58:29
beach
White_Flame: Thanks. I am not following the Python terminology, so I appreciate the information.
5:58:41
Dizidentu
I would stay but I just got back and I want to catch this flight into slumber land while I still can :|
6:01:17
beach
And, no, I think the purpose of Python is as a "scripting language", whereas Common Lisp is a general-purpose programming language.
6:05:50
White_Flame
because most people don't actually do core programming anymore, but rather call libraries (iow scripting)
6:07:51
beach
drmeister once showed us a site that gave the cost in electric power per computation unit for various languages, and Python is really bad.
6:16:24
parjanya
mornings! Is there a function, or an easy test... to check if an object can be printed readably?
6:24:35
beach
The answer would be influenced by things like methods on PRINT-OBJECT, and the existence of reader macros.
6:29:18
White_Flame
(handler-case (let ((*print-readably* t)) (write-to-string <item> nil)) (t (t) t))
6:31:10
White_Flame
actually, (ignore-errors (...try to print readably...) t), returning NIL if it isn't readable, is easier
6:33:53
parjanya
ah, very good idea, thanks! I tried finding a way to chase the method for printing, but no luck
7:04:16
White_Flame
I just tested with function objects, and those blew up when *print-readably* was set
7:10:23
White_Flame
if you truly do want to prune the values, then (values (thing-that-returns-multiple-values...)) does only return the first
7:18:23
White_Flame
"If printing an object readably is not possible, an error of type print-not-readable is signaled rather than using a syntax (e.g., the ``#<'' syntax) that would not be readable by the same implementation."
8:58:33
xificurC
yesterday someone pointed out I can define a package local nickname for a package, where can I do that? I don't see this option in the defpackage clhs page