libera/commonlisp - IRC Chatlog
Search
4:53:05
hayley
Oh, okay, this function is being called from another thread, so you cannot interrupt it that easily.
5:03:25
beach
asarch: You need to start reading the documentation of the Common Lisp implementation you are using.
5:09:26
beach
asarch: If you did that, you would have found this chapter: http://www.sbcl.org/manual/#Profiling
5:20:04
White_Flame
"regular" profiling instruments functions. stastical profiling just interrupts every N milliseconds and sees what functions are on the stack
5:25:31
mfiano
A nice side-effect of the latter is it annotates the lines of #'disassemble with sample counts
5:26:52
hayley
Also note that the counts tend to be on the wrong instructions, usually on the instruction after.
5:32:30
hayley
WITH-PROFILING won't work too well if you already have a server running, and additionally if you create new threads in the body, from experience.
5:32:41
asarch
Yeah: (sb-sprof:with-profiling (:max-samples 1000 :report :flat :loop t :show-progress t) (cpu-test 24))
5:33:50
asarch
In my case, I do: (defun foo () ...) and some other function calls it for me when the user visits "/foo"
5:34:32
hayley
(sb-sprof:start-profiling) <do some stuff you want to profile> (sb-sprof:stop-profiling) (sb-sprof:report :type :flat)
6:02:01
hayley
There's a fair bit of compiler noise, because you profiled loading the file too. But (SB-PCL::FAST-METHOD ELEMENTOS:RENDEREAR (ELEMENTOS:INDICE)) still sticks out.
6:04:29
asarch
" 1 617 25.3 880 36.1 617 25.3 - (SB-PCL::FAST-METHOD ELEMENTOS:RENDEREAR (ELEMENTOS:INDICE))"
6:18:42
hayley
One option would be to collect each rendered row into a string, and then concatenate from that list (e.g. (format nil "~{~a~}" rows)). Though it also would be a good idea to use a HTML library such as CL-WHO.
6:19:42
asarch
That function takes the code from the query, parses its components and the passes the result into the template to make this: https://pasteboard.co/7LEpyJx8qqZp.png
6:20:40
mfiano
hayley: In an email I sent him, asking him why he recommended others over his own in Common Lisp Recipes.
6:26:44
hayley
I don't think there are good answers for that question right now. You probably aren't going to concatenate strings any faster than CONCATENATE; you need to avoid concatenating big strings repeatedly.
6:27:20
beach
asarch: How big? I am asking because lots of people, even very smart ones, overestimate the amount of memory required.
6:27:54
hayley
beach: The problem is that asarch is performing (setf accumulator (concatenate 'string accumulator another-string)) in a loop.
6:32:39
mfiano
It seems most of that string can be cached at accessor writing time and read at render time.
6:35:56
asarch
However, which other way could parse every element of the original string, give a format and the save the result into a variable?
6:39:06
mfiano
If I understand correctly anyway. This is an algorithmic problem, not really that of a data structure (string)
6:44:22
asarch
A fellow from C# was talking about the ConcurrentBag object when you need multiple instances of complex objects and you don't want to allocate memory constantly
13:10:12
Bike
usually you write your project with a system definition .asd which includes external dependencies. if you then use quicklisp to load your project, it will take care of downloading anything you don't have downloaded. which is to say yes, but you probably don't want your project to actually use quicklisp itself unless it's a script kind of deal.
13:32:32
mfiano
Reminder: To anyone looking to have some fun this weekend (and all of next week in their spare time), the Lisp Game Jam friendly competition is kicking off tonight/tomorrow at midnight EDT: https://itch.io/jam/autumn-lisp-game-jam-2021
14:31:36
semz
There's also afaik still the problem that quicklisp doesn't verify downloads (has there been movement on that front?)
14:32:09
semz
it's one thing to do that on your own machine, but if you ship something that uses quicklisp in normal operation, your users will probably not appreciate that
15:00:23
JeromeLon
In a unit test, I want to check that a hook is called with the right argument. So I setup a special lexical witness variable, and update it from a lambda in the hook. But SBCL gives a warning, because there is no dynamic variable, even though everything is working fine. Any idea how I can improve this?
15:03:56
mfiano
JeromeLon: You are experiencing undefined behavior. Referencing a variable before defining it is not allowed by the standard.
15:07:10
White_Flame
but yeah, as far as this code goes, the specialness of *witness* only exists in that LET scope
15:07:50
White_Flame
if the INCF or access to *WITNESS* also exists outside that LET, then it would be handy
15:08:29
JeromeLon
beach: it's a setting that was extracted from a setting repository, and passed as an argument. There are many parts in the setting, the hook is the only one that can be EVALed
15:09:29
JeromeLon
White_Flame: right, but if all unit tests start to rely on defvars nothing is contained anymore
15:10:02
White_Flame
the defvar as well as the test function that uses it are all local to the testing package
15:10:45
JeromeLon
okok, so my solution only works by chance, and I should rely on a proper dynamic variable
15:36:51
JeromeLon
For reference, I tried on sbcl, clisp and ecl. In all cases, declaring the lexical variable special works: it's not BOUNDP, but the EVALed sexp has access to it. My test is (defun f1 () (let ((w 0)) (declare (special w)) (eval '(incf w)) w))
15:53:01
JeromeLon
beach: ok, how would you call it? "Dynamic variable that is only bound for the scope of the form that introduced it" is incorrect (BOUNDP is false).
15:58:33
beach
In your case (let (<stuff>)...) is the same as (let ((<stuff> nil))...) so your variable is bound in the scope of the LET.
15:59:39
JeromeLon
beach: I agree it is bound. I was mentioning BOUNDP because BOUNDP only returns true for dynamic variables, not lexically bound variables.
16:03:15
beach
Lexical variables are always bound, but there is no way to pass a lexical variable to BOUNDP.
16:11:49
JeromeLon
_death: nice, this fixes all my issues! No need for defvar, no warning, no global cluttering
16:15:14
_death
right.. still, I'd usually prefer defvar.. btw we've discussed all this last month I think, but september has been known at last..
16:16:01
Alfr
JeromeLon, does (boundp 'w) really tell you that w is unbound within the scope of that let? That's strange. (Precluding the case that you've makunbound it.)
16:20:17
beach
And it's not bound only within the scope of the let, but within the extent of the body of the let.
16:21:04
JeromeLon
Alfr: It's from my lambda than BOUNDP is false, even though it can access the variable (in https://pastebin.com/JzUqcTSG)
16:21:37
beach
So it is bound inside DECODE-SCALAR too, even though the body of the function DECODE-SCALAR is not in the scope of the LET.
16:21:43
_death
if you don't declare special at point of use, it's a lexical variable, e.g. check (funcall (let ((w 123)) (declare (special w)) (eval `(let ((w 42)) (lambda () w))))).. if the variable is free, some implementations take a lenient approach and look it up dynamic environment..
16:23:01
_death
"dynamic scope" is a colloquial term that means "indefinite scope and dynamic extent"
16:24:08
Alfr
beach, I thought that was clear from the context, as it's about that dynamic binding of W. Mea culpa.
16:25:59
_death
(you can also move the funcall inside the outer LET in the form I gave, with the same result)
16:31:21
JeromeLon
_death: "implementations take a lenient approach and look it up dynamic environment" this sentence explains everything. In particular, it explains why boundp is inconsistent with variable usage, I was finding this very confusing.
16:34:14
beach
JeromeLon: I suspect you are under the impression that the *...* inside your quoted expression refers to the binding in the LET.
16:39:02
JeromeLon
_death: no, I can't find the boundp returning false case again. I wish I had a better history of all my tests.
16:43:35
JeromeLon
anyway, when the code is consistent (using declare special both in the let and the eval), the behavior is consistent and clearly explained. And the initial weird case (eval having access to the special variable, even though nothing hints at it in its environment, but with a warning) has a reasonable explanation (lenient approach from the implementation)
16:46:47
_death
yeah.. SBCL warns you because generating that look-up code is not portable and perhaps not what you intended