libera/#commonlisp - IRC Chatlog
Search
6:08:18
flip214
How can I check whether some symbol exists in a package? Do I need to check (eq (find-symbol (symbol-name foo) (find-package :bar)) foo), or is there something like (package-contains (find-package :bar) foo)?
6:11:52
flip214
I'm also not entirely sure whether a symbol always has to have the same name in another package...
6:13:25
flip214
Can I intern eg. a GENSYM into a package later on? (SETF (symbol-package foo) ...) won't work, I guess)
6:16:04
flip214
WITH-PACKAGE-ITERATOR might be a way to find a symbol in a package, but it might be a bit slow for my purposes...
10:54:21
pjb
gin: instead of (lambda () t) which is a new function, or worse, (constantly t) which builds a new closure each time you call it, you could use a function such as (lisp-implementation-type) which will return a generalized boolean true value always, and which already exists in the image, and (eq (lisp-implementation-type) (lisp-implementation-type)) #| --> t |# so it doesn't even cons.
10:54:56
pjb
gin: (setf (fdefinition 'always-true) (fdefinition 'lisp-implementation-type)) (always-true) #| --> "Clozure Common Lisp" |# ;-)
10:56:53
pjb
flip214: you can set the home package of an uninterned symbol, by importing it in the package.
11:00:08
flip214
pjb: doesn't work for me. Value of SYM1 in (INTERN SYM1 :CL-USER) is #:X, not a STRING.
11:00:18
Alfr
pjb, also I'd expect an always-true to take arbitrarily many (up to call-arguments-limit) arguments.
11:13:33
pjb
Alfr: well, there are requirements that gin left unspecified, so (constantly t) is the best solution so far, despite its consing.
11:14:17
gin
thanks pjb for the messages. gave me a lot more to think about and learnt more lisp too
13:15:23
atgreen
I just updated sbcl (2.2.7) and quicklisp (latest), and now my app is generating "CORRUPTION WARNING in SBCL pid 16 tid 16:
13:15:23
atgreen
Memory fault at (nil) (pc=0x54100a44 [code 0x54100750+0x2F4 ID 0xc530], fp=0x7f94219ef4d0, sp=0x7f94219ef4a0) tid 16
13:17:51
hayley
I believe 2.2.7 now puts some constants in a read-only space after SAVE-LISP-AND-DIE, but then there would be a more instructive address rather than (nil).
13:19:43
hayley
The next step should be to work out how to get a backtrace; I think memory corruptions signal CL errors and so you can work it out from there. Or start SBCL with --lose-on-corruption (I think), then you'll land in a debugger called "ldb", and can issue the "backtrace" command.
13:21:01
atgreen
hmm.. this is a little complicated. the app is running on kubernetes, where it needs access to other kubernetes-hosted services to run. I can get in via sly, but will that give me an ldb prompt?
13:26:00
hayley
It won't, so I guess ldb might not be feasible then. You'd have to see if something is swallowing the generated exceptions.
14:47:48
dim
can I have a defmethod with an eql specifier on nil, like (defmethod foo (variant (eql nil)))?
14:49:41
beach
The AMOP uses the preposition "to" for specialization, and I think that's a good idea, so a method "on" a generic function specialized "to" null.
14:51:08
dim
well in my case I'm maintaining code that already has (defgeneric adjust-data-types (catalog variant) (:documentation "Adjust PostgreSQL data types depending on the variant we target."))
14:51:52
dim
it just happens that sometimes the variant is nil, I'm not sure why, and I'm okay with it being nil after all (two values are supported at the moment, :pgdg and :redshift, and nil would behave the same as :pgdg, I'm okay with that)
14:52:15
dim
(defmethod adjust-data-types ((catalog catalog) (variant (eql nil))) catalog) ; that's what I have in my code now
14:52:33
pjb
equivalent to: (defmethod adjust-data-types ((catalog catalog) (variant null)) catalog)
14:53:31
dim
given that context, I think I prefer the (eql nil) specified, it's better aligned with the intention here somehow
14:54:46
pjb
I think using (variant null) is more efficient than using (variant (eql nil)), but that would depend on the compiler.
14:58:04
dim
oh I don't have a perf issue there, it's done in a costly part of the code and only once
14:58:50
atgreen
Using --lose-on-corruption --disable-debugger worked. Corruption triggered in cl-postgres: https://paste.centos.org/view/51641cc2
15:01:07
_death
nasty (safety 0) in that function (parse-message-binary-parameters) which may hide something else
15:18:05
aeth
The user *may* choose to (safety 0) in a deployed application anyway to avoid type checks on tightly optimized code that has type declarations, but that's on them. Because now any bug that shows up in the real world is completely opaque unless you can reproduce it. And some library code may erroneously rely on type declarations to type *check*, which now becomes a type *assumption* in SBCL (safety
15:19:21
aeth
Imo, the only time (safety 0) makes sense is if you absolutely positively must avoid bounds checking inside of a loop where you're absolutely sure that you can't go out of bounds, but that can go inside of a LOCALLY to limit the damage. And the implementation can ignore you and bounds check anyway.
15:20:24
aeth
But... that sort of loop usually is operating on data of defined sizes so you usually can get an optimizing compiler to avoid bounds checking by just letting it know that the type is, say, (simple-array single-float (42)). And now something smarter than you is eliminating bounds checks (or not).
15:22:00
aeth
And do you really need the extra speed at the expense of dealing with strange out of bounds bugs? Because that's one of the worst parts of C or C++.
15:22:01
_death
atgreen: I guess submitting a patch would be ideal, but note that you can also restrict optimization settings using sb-ext:restrict-compiler-policy
15:22:54
aeth
99% of code that says `(safety 0)` just recited an incantation off of the internet without realizing the implication to SBCL users (probably > 2/3 of the users of the code in 2022)
15:34:59
NotThatRPG
White_Flame: That has the effect of switching on the "come-from" operator, too! ;-)
16:10:04
jeosol
_death, aeth: I don't remember, does that (declare (optimize (...)) affect all code if done at repl and you load a large system?
16:11:20
pjb
Let the user decide on what he wants. He'll set the optimization levels in his rc file.
16:11:37
jeosol
I was doing some exploration weeks ago, but I didn't see any effect, so thought I didn't set it up correctly
16:12:49
Fade
does asdf have any facility for declaring optimisation level in a given build component?
16:18:15
jeosol
pardon my mixing up the terms. I was referring to setting compiler optimization policies referenced earlier
16:28:39
White_Flame
jeosol: I believe that's undefined how it spreads across future loads and whatever
16:29:30
White_Flame
I tend to build some form of configuration parameter for optimization, and have scoped declarations for different sections as they need it
16:29:52
Bike
"As with other defining macros, it is unspecified whether or not the compile-time side-effects of a declaim persist after the file has been compiled."
16:30:00
jeosol
Trying to add that at code or file level is not feasible for me, so I'll just work with the rc level if that works
16:31:08
White_Flame
"Such a declaration, sometimes called a global declaration or a proclamation, is always in force unless locally shadowed."
16:31:52
jeosol
After my limited tests, I just use the defaults for now, and just focus on the DSA bits in the code and look for any improvements
16:33:52
White_Flame
as long as your image lasts through all compilation, I would suspect that has some effect
16:34:30
White_Flame
then there's also ASDF to consider and what it might shadow for its various compiles & loads it orchestrates
16:43:26
NotThatRPG
White_Flame: ASDF does not attempt to shadow, but does nothing to avoid systems it loads from affecting global context of the image. Again, because the spec is so unclear, ASDF doesn't have the ability to do anything portable, so just punts.
16:43:30
_death
jeosol: in computation-intensive code declarations can help a lot, so if you already use good algorithms and data structures, you may still benefit by sprinkling them after profiling (maybe after other performance-related operations, such as reduction in consing or caching)
16:44:17
NotThatRPG
_death: On a function-by-function basis, this is easy and its effects predictable. Trying to build an entire system with (optimize (speed 3)) on the other hand...
16:46:11
jeosol
_death: yes, that is my plan exactly. I go through the code sections that were written in a hurry and rewriting to avoid unnecessary calculations or consing. It's small stuffs for now. I really on an external exe for benchmarking but hope to write replicate the code in the exe in the future
16:46:25
_death
NotThatRPG: indeed.. sometimes it's even more localized.. for example I have a macro where I know the body is going to run for many iterations and often needs performance, so I declare (speed 3) in a locally there.. but then, a few uses aren't critical, so I have to reintroduce (speed 0) (or should it be speed 1? :) manually
16:46:49
jeosol
the exe code is basically Ax=b type systems that are solved repeatedly (fluid mechanics problem)
16:50:46
_death
NotThatRPG: maybe I should split the uses and have two operators instead (another option would be to pass an argument, but I don't think I'd like that)
16:51:35
NotThatRPG
Macro argument that controls whether or not the `(locally (declare (optimize (speed 3))))` goes into the expansion?
16:54:03
_death
sometimes I just keep the default (speed 3) and add a type declaration or two to avoid the compiler notes.. but I think two operators could be a better signal to the human reading the code
16:58:25
jeosol
I am discussing with some folks next week who may ask: what is the CL macros I talk about. I saw this link: https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node97.html#:~:text=The%20Common%20Lisp%20macro%20facility,as%20in%20most%20other%20languages. which I think is good. I don't think they'll understand but I can try to explain in layman terms
16:59:15
jeosol
basically, I use macros to generate a lot of functions that have symmetry in the function body.