libera/#commonlisp - IRC Chatlog
Search
11:09:37
phoe
as always with inheritance, it is up to you to resolve all interactions between your superclasses
13:54:59
jackdaniel
as of minion, I don't know who is responsible for moving this bot. I remember stassats managed it at some point of time. either way, -> #common-lisp.net
14:11:21
rdrg109
beach: Yes. I'm a Common Lisp newbie (1 week), so I don't know all the available options. I would appreciate if you could point me to some resources that might help me understand what are the differences between Clisp and the other available ones.
14:11:30
rdrg109
I'm currentlyu using https://lispcookbook.github.io/cl-cookbook/ as my learning resource
14:14:12
beach
rdrg109: CLISP is not used by many here, so if you run into problems, you may not get as many people to help you.
14:14:56
aeth
The problem with using CLISP (even just to test) is that even CL isn't an unchanging language and CLISP hasn't gotten a release in just under 11 years, so it's missing extensions that some libraries might assume.
14:15:00
aeth
CLISP is also missing useful features that it never had, e.g. specialized-arrays for simple float types like single-float and double-float that every other implementation has. It won't break code, it'll just deoptimize it and remove some runtiem checks that might be assumed.
14:16:36
pjb
but clisp is still maintained, you can use git to get the latest version. The same is true with ccl by the way, which hasn't had a new release for 14 months!
14:16:38
aeth
What sets CLISP apart is that CLISP is one of the few interpreters rather than compilers, so its memory usage is much lower (but it's much slower). It's also used in the bootstrapping of some implementations (since you might need CL to compile a CL), unless people have finally ported that over to something like ECL.
14:17:13
aeth
pjb: there's a difference between 14 and 131 (almost 132) months. The difference is an order of magnitude.
14:17:50
pjb
aeth: but still. Also, there seem to remain still a lot of bugs in sbcl, which justifies its monthly releases…
14:17:54
aeth
fwiw, I don't test on CLISP and I don't even bother to make sure that my code runs on CLISP, because some dependency-of-dependency-of-dependency is always broken on it and I write large programs.
14:25:07
aeth
Although ime, if you add enough libraries, you're probably only going to run in SBCL, CCL, and ECL... and I'm not sure about ECL. (To be fair, I don't even consider paid implementations let alone test on them.) In particular, ABCL likes to break things by implementing things differently because of its different environment (the JVM).
14:30:18
aeth
pjb: as for sbcl's bugs, it's more like... optimizations are infinite work because there's always something else to do for an extra 5%, which adds up
14:30:32
loke[m]
aeth: well, you can also download GCL which also gets patches so should be classified as being maintained.
14:35:21
makomo
is it legal for a toplevel function to be named by a gensym? something like (defun <gensym> (...) ...)
14:35:43
makomo
(assume that the <geynsym> is placed there by a macro that generates the defun form, or maybe a reader macro, or something)
14:37:13
makomo
jackdaniel: i was just wondering because i have a macro that creates a gensym-named function wrapping some user-provided code, along with a "normal-named" macro that calls that hidden function
14:37:42
makomo
but i'm having some issues so i wanted to double check. something might be wrong with the body of my macro perhaps
14:39:28
jackdaniel
(defmacro defpun (name args &body body) `(setf (gethash ',name *hash-table*) (lambda ,args ,@body)))
14:39:36
makomo
but i'm wondering whether doing this gensym thing is a good idea for what i want to achieve
14:42:20
jackdaniel
rdrg109: people usually first pick sbcl, then ccl and after that whatever fits their niche purpose (i.e ecl works fine on android and inlines C/C++ code, abcl works fine in jvm etc)
14:42:31
makomo
i guess what i really want is for my "hidden" function to have a deterministic name, yet not clash with any of the user's symbols
14:42:53
makomo
so i guess i could either go for the hash table approach that you suggested, which avoids using defun in the first place
14:42:55
jackdaniel
as of people who do not test their libraries for portability- oh well, that's their right
14:43:32
makomo
or if i really wanted to use defun, i could use some sort of private package and come up with a deterministic scheme of generating unique symbols based on some name given by the user
14:44:24
makomo
jackdaniel: what if multiple people decide to use my macro and give the same name as the argument?
14:45:41
jackdaniel
then the evaluator will need a client argument either way. then the hash table keys could be (cons client name), or the client could be a hash table itself
14:47:07
shka
makomo: btw, depending on what kind of wrapping you want to do, you may prefer to use thunks
14:47:11
makomo
_death: i also thought of that, but ehhh, sort of wanted to avoid symbol plists (for nog ood reason)
14:49:34
makomo
jackdaniel: hmm, i'm not sure if we're thinking of the same thing by "different pools of functions"? what do you mean by "it will need a client argument either way"?
14:49:36
shka
wrap user defined code in a lambda form, pass to a higher order function which will also perform some sort of cleanup
14:50:05
jackdaniel
makomo: say two clients define a function (defpun a () 'xxx) and (defpun a () 'yyy)
14:51:29
makomo
because if they're eq, then it would just overwrite the previous def, which is fine with me
14:52:00
shka
makomo: honestly, i personally really don't like implicit function names, i came to prefer explicit names required
14:52:21
makomo
jackdaniel: so if i want this hidden function to have a nice name for each usage of defpun, i would have to come up with some scheme of generating unique names based on the given symbol
14:52:22
pjb
(progn (defun #1=#:foo () 'foo) (defun goo () (#1#))) #| --> goo |# (goo) #| --> foo |#
14:53:21
makomo
shka: me neither in that sort of context, but the user would never actually use them
14:53:50
makomo
it's just for a "pretty implementation" so to speak. however, if gensym-named funcitons work just fine, then it shouldn't make a difference i suppose
14:55:19
makomo
jackdaniel: one thing that came to my mind regarding the hash-table idea is the issue of concurrency maybe, although i didn't think about it that much. i wanted to avoid having to think about synchronizing access to this hash table which acts as a global repo of function names, which i think i would get for free if i just used the impl's defun. is that a valid concern?
14:55:53
splittist
makomo: you might want to save extra information - who defined, when, defining form ...
14:56:23
makomo
splittist: i.e. use all of that extra info to generate a nice unique pretty name, or something else?
14:57:37
splittist
I was thinking that would be easier if you had a user-function object in a hashtable (or list, or ...)
14:58:19
makomo
ah that's what you meant. right, if i use a hash-table, then i already have a unique identifier that the user provides anyway, so that's all good
14:58:48
makomo
i'm wondering about the concurrency issue with hash tables outlined above though ↑↑↑↑
15:01:08
makomo
Bike: interesting, but i think that's a separate issue (and my impl would have that same issue). i just didn't want to worry about synchronizing adding new entries into the hash table and similar
15:02:20
makomo
are you talking about the issue where a thread might continue executing the old version of a function's body even after the function's redefined?
15:04:25
jmercouris
I find myself writing (setf some-value (or (uiop:getenv "xyz") "some-default")))
15:05:23
jmercouris
now, of course this could be seen as bad style, because neither are booleans, nor am I treating them as booleans...
15:06:34
pjb
jmercouris: you would write (let ((x (uiop:getenv "xyz"))) (if (not (null x)) x "some-default")) but (macroexpand-1 '(or (uiop:getenv "xyz") "some-default")) #| --> (let ((#:g21415 (uiop/os:getenv "xyz"))) (if #:g21415 #:g21415 "some-default")) ; t |# this is exactly what OR does!!!
15:10:25
shka
however, writing or all the time is kinda boring so i would add my own function anyway
15:10:55
makomo
shka: the 2nd issue is something that needs to be considered per-function (or per-expression) anyway, right?
15:12:47
makomo
Bike: right, but my issue is that since this global hash table is not synchronized, multiple threads evaluating my form might end up clobbering the hash table which ends up in a definition being lost, right?
15:14:01
Bike
makomo: i don't understand. if you have two different threads redefining a function in different ways, one of those definitions is going to be lost
15:14:59
Bike
you have two threads doing different things to the same place, one of them's goign to lose.
15:15:23
makomo
Bike: sort of, yes, but also no because the solution with DEFUN doesn't have that issue. it's another thing i would have to take care of
15:15:55
Bike
there's no guarantee. this is not defined behavior. the implementation might use a global table for function names anyway
15:16:04
makomo
really? does that mean cl impls don't guarantee that evaluating DEFUN accross multiple threads is "safe"?
15:16:22
makomo
Bike: true, and threads aren't even defined by the spec, right? but any impl that implements them surely takes care of this?
15:16:53
rdrg109
[Q] cl newbie here. I've started using sbcl + slime in Emacs. I've two questions: (1) Let's say I want to know more about the "princ" function. Where can I get information on that function. (2) How can I get a list of all ANSI Common Lisp functions?
15:16:55
makomo
jmercouris: that could be one situation, but i assume some impls might have a way of loading/evaluating code in parallel or whatever
15:18:43
Bike
i mean in normal use you only defun when you're editing code. it's not something you do problematically. so this doesn't come up.
15:19:20
Bike
what i'm saying is that this doesn't come up in practice so implementations don't bother
15:19:43
makomo
Bike: so does that mean that implementations don't usually evaluate/load code/systems/whatever in parallel?
15:20:16
Bike
there was an asdf extension that was supposed to do that, but it worked by forking rather than threads
15:20:33
Bike
in sbcl, there's a giant lock around the compiler, so you can't simultaneously compile anyway. or at least that was the case when i last looked at it a while ago
15:21:29
Bike
defun might involve changing multiple things, e.g. the fdefinition, any saved inline definition, global ftype proclamations
16:06:00
Guest63
https://www.reddit.com/r/lisp/comments/o5bqb6/lispers_active_anywhere_else_with_a_better/
16:09:58
jackdaniel
logging is one thing, but irc discussions are more or less ephemeral anyway (without any organization)
16:10:09
pjb
Perhaps you could manage a nntp server with some authentication to avoid spammers and we could restore the glory of past comp.lang.lisp?
16:10:44
jackdaniel
i.e if I had answered to what Bike said a week ago I doubt that will be intelligible
16:12:00
Guest63
(I may be wrong since I don't use mailing lists) but the issue with mailing lists / IRC is discoverability
16:14:42
Guest63
beach: honestly I don't know. I just used forums for other things and prefer them to reddit
16:15:57
Guest63
Projects would be better on GitHub Issues / GitLab, Q&A would be better on Stack Overflow, Chat / Quick responses would be better on IRC, memes on Reddit --> So I don't know
16:16:28
jackdaniel
that said I think that old forums were much more useful than facebook, reddit and other attention-seeking platforms
16:17:03
Guest63
_death: indeed :) Which is a scary thing (except SO, I think that one is safe for now)
16:17:05
jackdaniel
(i.e they didn't try to addict you to use them; many smart people work on that shameful practice)
16:17:38
edgar-rft
I'd say that not finding answers in mailing lists is a poverty of Google, not a bad thing of mailing lists
16:17:44
Guest63
jackdaniel: thanks, that's basically where I"m coming from - there always going to be a bit of attention seeking / blog posts / news etc, and a forum is better for those imo
16:18:38
jackdaniel
that said, mailing lists are quite good for discussions (when you have a topic to discuss - compared to posting cat pictures ;)
16:19:01
_death
you could also blog using mailing lists.. I'm thinking of the old kragen-thoughts list
16:22:01
pjb
Guest63: you can make your mail list discoverable, by puting their archives on the wbe.
16:25:38
Guest63
pjb: I'm waiting for lisp programmers to be in short demand, then I will get a professional job writing lisp :)
16:25:38
pjb
Guest63: but you'd definitely need to filter it, given the number of spammers and idiots who broke it.
16:27:10
pjb
Also, libera has a new rule: Nickname and account registrations expire ten weeks after they are last used. So you can expect me to not come back after my next holidays.
17:56:17
jcowan
on SBCL exts: this problem really bites in Scheme, because people get used to using non-portable stuff because they need to, and when some portable API comes along they don't switch to it. And of course the ANS is much larger than any Scheme standard hitherto
18:23:07
phantomics
Is there a reason (gcd) and (lcm) don't work with ratios? Writing a version that works with ratios simple - multiply both by the product of denominators, take the gcd/lcm of the result and divide the result by the denominator product. Is there a gotcha I'm missing?
18:25:47
Bike
what is the definition of gcd and lcm on ratios? i've always understood them as integer operations
18:33:33
Bike
what you describe seems wrong even if we extend the definition to be the largest ratio that divides the inputs
18:33:40
susam
phantomics: As per your definition gcd(1/2, 1/6) = 1/6. Right? After multiplying by the product of denominators, we get 6, 2. Their gcd is 2. Then 2/12 = 1/6. But gcd(1/2, 1/6) = 1/6 does not make sense. Why 1/6? What is special about 1/6? Why couldn't the answer be 1/2 or 1/4 or some other fraction?
18:35:55
susam
I mean, we need to first define divisibility for fractions in a sensible manner. Otherwise it would appear that every fraction divides every fraction. Given p/q and r/s, surely (p/q)/(r/s) is another fraction.
18:37:05
susam
For integers, divisibility is neatly defined. d divides n if there is an integer c such that n = cd.
18:39:16
susam
Bike: in that case 1/24 does not divide 1/18 because the quotient is (1/18)/(1/24) = 24/18 = 4/3, not an integer.
18:44:12
phantomics
APLs allow for gcd and lcf of fractions (most implementations only have floats, not ratios), 1/36 is also given as the result by Dyalog and GNU APL
18:45:01
susam
Yes, with the definition that p/q divides r/s if r/s = c(p/q) for some integer c, I think it will work.
18:46:28
Quasus
if a ring happens to be a field, then everything (except zero) divides everything, as susam notes
18:48:40
Quasus
"d divides n if there is an integer c such that n = cd" doesn't work in general, e. g. for polynomials; sure we'd like x + 1 to divide (x + 1)(x + 2)
18:49:45
phantomics
Guest63: When will you know the dimensions? This sounds like a hash table not array
18:50:35
Guest63
Actually that's a good idea, I was trying to create attribute1 x attribute2 array, but I can just do (attribute1 . attribute2) as a key to the hash table!
18:59:03
Josh_2
I came up with a good (maybe) use for MOP, defining categories of 'hooks' into my system where the class is the category and each slot is an individual 'hook' that is executed, and then args to each hook are defined in the class definition. Although I guess this would mean I couldn't easily add new hooks without changing the class definition
19:00:31
susam
phantomics: So stated concisely, gcd(p/q, r/s) is defined to be gcd(ps, rq)/qs. It is a reasonable definition for the expressed intention.
19:00:58
susam
phantomics: By the way, do you come across any practical usefulness for such a gcd definition?
19:07:37
phantomics
Also http://dfns.dyalog.com/c_rational.htm which they use to convert float to rational
19:09:17
entre-parenteses
Is anyone aware of any work being done to (eventually) have an implementation target WebAssembly? I know it's not completely possible, yet, due to lack of certain features in WebAssembly - i.e. GC is the main one that comes to mind - but I'm curious if anyone knows of any work being done along those lines.
19:12:28
Bike
clasp uses llvm so webassembly isn't that far off, but putting a several-hundred-megabyte lisp image into a webpage seems kind of silly
19:13:38
entre-parenteses
Bike: Yeah, I looked a bit into ECL, so far, but I haven't made it very far with that.
19:19:03
phantomics
Would make sense for a locally-hosted Lisp environment interfaced through the browser, it could talk to remote Lisps
19:26:14
entre-parenteses
_death: That's right! I came across it a few months ago (but forgot about it). If nothing else it could be a good jumping-off point.
20:14:32
phantomics
Here's some discussion about wasm/CL concerns: http://article.gmane.org/gmane.lisp.steel-bank.devel/19495
20:24:10
rdrg109
[Q] newbie here. Just as I can create tests for Emacs packages through the ert package. Is there any widely used package for testing Common Lisp modules?
21:01:56
entre-parenteses
phantomics: Thanks for the reference! I'm having trouble accessing the gmane.org article but I'm reading through the PR comments - hopefully that covers most of what's discussed.
21:56:03
sm2n
kind of late and Guest63 seems to have gone, but for posterity—SO is bigco now as well, it got bought out recently
22:00:42
rdrg109
I'm gonna put it clearer: I've recently installed Quicklisp and the documentation mentions that to install a package, you need to execute (ql:quickload system-name), but before doing that I would like to know the docstring of ql:quickload to understand what it does
22:01:59
sm2n
there are many ways to do it, but easiest is probably C-c I #'ql:quickload to open it in the slime inspector
22:17:28
rdrg109
[Q] Thanks for the help! All of them worked. Another quesstion: Let's say I install a package with (ql:quickload "package-name") How to list all the functions that are defined by a given package?
22:19:22
Bike
(loop for s being the symbols of "package" when (fboundp s) collect s else if (fboundp `(setf ,s)) collect `(setf ,s))
22:19:51
Bike
a given quicklisp system may have any number of packages, and the names of any packages defined don't have to coincide with the name of the system
22:20:03
_death
(package-name: C-c C-i ... you could also use lisp's introspective capabilities.. (remove-if #'fboundp (apropos-list "" "PACKAGE-NAME")) ;; homework: write a better apropos