freenode/#lisp - IRC Chatlog
Search
23:29:42
jasom
stylewarning: sbcl lets you disable package locks, so you can on at least one specific implementation
23:34:17
stylewarning
jasom: I need to learn more about these neat features of SBCL. I usually scan the manual every so often, but I guess I missed/forgot this.
23:36:39
scymtym
stylewarning: speaking of which: we just made the manual look a little nicer and documented the different kinds of timeouts in SBCL
23:49:36
scymtym
didi: we just applied a different stylesheet to the HTML version. does that alleviate your concerns?
3:26:06
borei
i have question about lisp code optimization - matrix multiplication in my case. i undestand that topic is rather big, but still, some recommendations would be nice. I was trying to find best solution in C/C++ but didn't get explicit answer for it
3:27:23
borei
i store matrix elements in 1-dimensional array (simple-array) - that guarantee that data will be continouse
3:28:40
borei
to multiply matricies i can create nested loop with proper indexing, so it will do proper elements multiplication
3:29:29
borei
or i can pull row(s) and column(s) from input matricies and do multiplication (scalar multiplication) on them
3:30:50
borei
in second approach im hoping that vectors (rows and colums) will fit cache, but i can't control it
3:32:37
borei
in first approach more or less big matrix will not fit cache for sure, but there is no overhead on moving data, only access to elements
3:33:32
borei
there is 3rd approach - block matrix multiplication, but it's more complex in terms of the algorithm
3:36:50
pierpa
by copying parts of the arrays somewhere else you won't diminish the amount of cache needed. On the contrary.
3:41:24
borei
pierpa: i was hoping that when i extract row (or columns) from matrix it will fit CPU cache, and multiplication will be done much faster, comparing pulling out individual element from huge array
3:42:15
pierpa
the extracted column may fit the cache, but to extract the it in the first place you have to traverse the data in the matrix, no?
3:43:13
pierpa
since you are traversing the matrix just multiply the numbers rather than copying them somewhere and then multiplying them
5:29:29
beach
I am not an expert, but I know there are better ones. See for instance: https://en.wikipedia.org/wiki/Matrix_multiplication#Algorithms_for_efficient_matrix_multiplication
5:31:01
beach
borei: I think if you are going to build a library for such things, you need to read up on current best practice.
5:31:45
beach
borei: Careful though, it looks like Strassen's algorithm is based on the idea that multiplication is way more expensive than addition. That may no longer be the case.
5:32:51
beach
borei: Also, since all modern Common Lisp systems have threads, you may want to investigate parallel algorithms for use when the matrices are big.
5:34:43
beach
borei: But then again, perhaps your goal is not excellent performance. I was just guessing that since you mentioned execution time.
5:36:42
beach
It is a vast domain that many very smart people have been working on for a long time, so yes, there is a lot of reading to be done.
5:52:15
jack_rabbit
I've noticed in some .asd files that keywords are prefixed with '#'. What is the difference between e.g. :foo and #:foo?
5:57:55
jackdaniel
if you use foo in asd definition, you "pollute" asdf-user package (or whichever package you are in)
5:58:02
jack_rabbit
I see. So it's just to avoid interning the symbols, since they're only needed for loading.
5:58:51
jackdaniel
yes, especially that they are used only for their names. afair asdf coerces them to downcase strings anyway
6:13:55
beach
jack_rabbit: It is not only a matter of avoiding the "pollution" of the keyword package. It is also a message to the person reading your code, that the package of the symbol does not matter. If you use a keyword, then the person reading your code can't immediately know whether the package is important or not.
6:18:05
jack_rabbit
beach, aren't keywords package-independent? Or rather, they are all interned into the keyword package? When would the package be important when using a normal keyword?
6:20:06
jackdaniel
jack_rabbit: it may be important for instance in eq comparison (which you have mentioned)
6:20:43
jackdaniel
or take example, which is untrue for asdf: systems are represented by symbols (not strings) - in such scenario you could specialize methods via eql
6:20:56
beach
jack_rabbit: A keyword is by definition a symbol that has the KEYWORD package as its package.
6:22:16
jack_rabbit
jackdaniel, so I would use non-interned symbols when I don't care that they are eq.
6:22:35
beach
jack_rabbit: There are a number of situations where the package of a symbol is important. For example, if you do (find ... :test ...) you can't do (find ... #:test ...) and expect the same result.
6:23:26
beach
jack_rabbit: No, you would use uninterned symbols when you want the person reading your code to know that the package of the symbol doesn't matter.
6:23:32
jackdaniel
jack_rabbit: that's not exactly what I meant. If systems were represented by symbols, you wouldn't want to use uninterned symbols at all, you'd want to use interned ones instead (all the time). but this is only hyphotetical situation
6:24:42
jack_rabbit
jackdaniel, Yes, I get that. But that is due to the fact that you'd want to be able to compare the symbols and determine that they are eq or not, right?
6:25:50
jack_rabbit
beach, Sorry, maybe I'm being dense. I don't get the association with package. Can you give an example of when the package does not matter?
6:25:54
beach
jack_rabbit: EQ comparison is one possibility, but I can see situations where nobody cares about EQ, but the package is still important.
6:26:15
jackdaniel
not only that – imagine hypothetical function find-system. you don't care how it is compared, but if it is implemented to work on symbols then you wouldn't be able to look for a system denoted by a specific symbol
6:27:00
rme
people often use uninterned symbols (and keywords) as string designators. Instead of writing "FOO", they write :foo or #:foo
6:27:02
beach
jack_rabbit: One such example is in the name of the symbols exported in a DEFPACKAGE form. These names are used only as string designators.
6:28:16
jack_rabbit
beach, So with keywords, you say that the package is still important because the fact that they are all in keyword package has consequences?
6:29:08
jack_rabbit
Because to me, it seems that keywords are a way to use symbols without regard to a particular package (except implicit keyword package I guess.)
6:29:40
jack_rabbit
OK. So the only time non-interned symbols are useful is if they are used as string designators?
6:30:05
stylewarning
jack_rabbit: they are also useful when you wish to produce symbols for bindings
6:30:20
beach
jack_rabbit: I am not saying that the package IS important for ALL uses of keywords. We already had an example of that, e.g. when you use a keyword as a string designator. I am saying that the person reading your code MUST ASSUME (until proven wrong) that the package of a symbol is important, unless it is an uninterned symbol.
6:30:37
phoe
(let ((gensym '#:foo)) ...) - though this is mostly abstracted away via #'GENSYM and ALEXANDRIA:WITH-GENSYMS.
6:31:14
phoe
and what beach said - using an interned symbol implies that the package *may* be important in that context.
6:31:42
phoe
doesn't have to be, like LOOP discards package information for its loop keywords, but in general, you can't rule out the possibility.
6:32:01
beach
Exactly. So you put an additional burden on the person reading your code by being less specific than you could be.
6:32:54
phoe
jack_rabbit: because you generate the symbol once and put the same generated symbol in all the places.
6:34:11
jack_rabbit
phoe, yes. Because something is bound to the instance of the symbol, I can reference the same symbol in multiple places through the binding.
6:34:49
phoe
LET only wants symbols that already aren't constant variables so it can bind lexivars to them.
6:35:42
jack_rabbit
I just mean, I understand that the reader reads each instance of #:foo as a different symbol, but with the gensym, I'm binding a particular instance and reusing that, which is why it works, right?
6:37:40
flip214
is there some machine-readable version of ROOM? One that returns an alist or plist or so?
6:38:01
phoe
So (list #1=(make-hash-table) #1# #1# #1#) will give you a list of four elements. All of these elements will be EQ to each other, meaning they're the same object.
6:39:05
phoe
jack_rabbit: not really. The integer is used as a reference number internally in the reader.
6:39:40
phoe
So (list #1=(make-hash-table) #2=(make-random-state) #3=(make-array 10) #1# #2# #3#) works.
6:40:18
phoe
flip214: definitely not a standard thing. ROOM prints to standard-output, and it's implementation-dependent so it may print nothing in the most degenerate case.
6:42:09
flip214
phoe: yeah, that's why I'm asking. so no TRIVIAL-ROOM or similar library yet, right? Thanks anyway!
6:44:05
phoe
Because the RECURSIVEP setting preserves the #1# bindings if set. If it is not set, they are started from scratch.
6:46:39
jack_rabbit
That makes more sense than what I assumed, which is that they were preserved between read calls.
6:46:42
phoe
You can think that a toplevel READ does something like (let ((*sharpsign-sharpsign-bindings* (make-hash-table))) ...)
6:49:24
jack_rabbit
It must also check if it's actually bound, too, yes? Or can I not set RECURSIVEP to t if I'm not already in a call to read?
6:51:12
beach
jack_rabbit: No, RECURSIVE-P is a lexical argument to READ, so it is not accessible to you.
6:51:33
phoe
"If recursive-p is true, the call to read is expected to be made from within some function that itself has been called from read or from a similar input function, rather than from the top level. "
6:51:35
beach
jack_rabbit: Just like if you do (defun f (x) ...) you can't set X unless you are inside the call to F.
6:51:56
jack_rabbit
So I would assume I cannot set RECURSIVE-P if I'm not already in a call to READ.
6:52:22
beach
jack_rabbit: But you are never "in a call to READ" unless you edit the code of the READ function
6:54:04
beach
jack_rabbit: The only code that can assign to the variable RECURSIVE-P is the code inside the READ function, just like my F and X example.
6:54:44
jack_rabbit
beach, by "set RECURSIVE-P" I mean call read with argument RECURSIVE-P equal to t.
6:55:33
beach
jack_rabbit: You can always pass whatever value you want for RECURSIVE-P to your call to READ.
6:55:35
phoe
you can all MACROEXPAND, for example, which does not require #'READ to be on the stack anywhere.
6:57:53
beach
Like I said, nothing prevents you from calling READ yourself with RECURSIVE-P equal to a true value.
7:00:02
beach
"If recursive-p is true, the call to read is expected to be made from within some function that itself has been called from read or from a similar input function, rather than from the top level. "
7:00:40
phoe
Therefore it might be UB if there is no non-recursive READ on the stack but you call a recursive READ.
7:00:54
beach
So I take that to mean "the consequences are undefined if READ is called with RECURSIVE-P being true at the top level".
7:04:45
beach
jack_rabbit: Passing a value as an argument to a function ESTABLISHES A BINDING for the corresponding parameter. Establishing a binding for a variable is a very different process from that of SETTING the value of a variable.
7:05:36
jack_rabbit
beach, I am not confused about that. Again, I interpreted phoe's statements as a convenient shorthand for what we were talking about.
7:05:47
yggdrasil_core
so, has anyone here gotten renderdoc to work with a common lisp program using cl-opengl in sbcl?
7:07:42
yggdrasil_core
I figure it's a streatch but I can't get the two to work together and it is making debugging my texture loading hard
7:08:17
phoe
yggdrasil_core: just a random thought, people over at #lispgames might have more experience with OpenGL in CL
7:09:51
phoe
It's hard to figure out general cases like getting X to work on Y, and easier to figure out why error X happens with stacktrace Y.
7:10:50
yggdrasil_core
when I set it up to run the binary it just either doesn't open it, or it immediately closes, when I inject into the process it just doesn't capture anything
7:12:54
yggdrasil_core
I use save-lisp-and-die to produce the binary, which does work just fine when ran outside of renderdoc
7:16:08
yggdrasil_core
unless you mean to see how far it is getting when renderdoc starts it (if it is actually starting it)
7:17:01
yggdrasil_core
I'm not, but thats because in this particular case I don't think there is an error happening :p
7:17:58
yggdrasil_core
I'm submitting texture data and having problems with it being loaded right, because I am not sure what pngload is giving me ._.
7:27:54
yggdrasil_core
was it the one that posts a bunch of square characters and then highlights everyone in the channel?
8:26:47
jackdaniel
first advice: state the program goal in question or in comments in snippet, I don't know what kind of advice do you expect
8:27:31
jackdaniel
fourth advice: don't put main program in toplevel, define function for it (and eventually call it toplevel)
8:36:41
jackdaniel
if you don't need macros don't use them (this is a rule of a thumb, when you known what you are doing you may bend this rule of course)
8:37:01
minion
asdfjkla: have a look at pcl: pcl-book: "Practical Common Lisp", an introduction to Common Lisp by Peter Seibel, available at http://www.gigamonkeys.com/book/ and in dead-tree form from Apress (as of 11 April 2005).
8:44:03
jackdaniel
asdfjkla: start with making these variables arguments for your function, not globals
8:55:30
jackdaniel
since current-word is result of computation on word and guesses, you may have (Defun hangman (word guesses) (let ((current-word (current-matches word guesses))) …))
10:35:06
beach
I started working on rules for indenting Common Lisp code. Here is a first version of what I came up with: http://metamodular.com/indentation.pdf
10:40:11
beach
For a multi-line string, the beginning of the string would be indented as usual, and the rest of it, just left alone.
10:40:36
beach
Comments are part of the parse result, so in the case of ;; they are indented with the code.
10:42:45
phoe
if a function accepts &key args then slime seems to figure it out and indent accordingly.
10:42:54
beach
flip214: Pairs like that are not a problem. The rules only compute the indentation of the first parse result on the line.
10:43:43
phoe
beach: I suggest that you include that. &key args are pretty important to indent properly because they tend to come aplenty at times.
10:44:17
phoe
Also I suggest that you spend a little bit of time on indenting macro lambda lists, too.
10:45:26
phoe
Since most Lisp forms are function/macro/specop calls, and these have their lambda lists and lambda lists keywords.
10:50:51
phoe
The moment your editor has utilities for paren matching and ability to do general indentation, then it has the two utilities required for sane Lisp writing.
10:51:22
Colleen
About trivial-indent https://shinmera.github.io/trivial-indent#about_trivial-indent
10:57:29
flip214
beach: yeah, but I meant that if you can derive that the arguments are pairs (or, generally, N-tuples ;),
10:58:04
flip214
you could have the second part of the pair (or the later parts of the tuple) indented one level deeper
11:10:42
flip214
or, if they are on the same line, it would be nice to have the non-first-tuple-parts aligned, too.
11:12:06
flip214
but first part aligned, second aligned, and two spaces min to signify the separation is my favourite style
11:19:16
beach
flip214: Ah, yes, I see what you mean. Either way, may standard macros would have their own rules, so I am not worried about SETF.