freenode/#lisp - IRC Chatlog
Search
11:43:58
schweers
it is a sad state of affairs that I prefer elisp to most mainstream languages out there
12:09:41
jcowan
"This interface implements only 10% of <random foreign library> cuz that's all I needed. YMMV."
12:23:31
sheepduke
Hey, does anyone know how does clack handle static files? (Like CSS file included in a HTML etc)
12:33:43
jcowan
often it's subtly wrong, and so people either fork it or discard it, and pretty soon everyone is effectively using their own code again
12:34:03
schweers
the more it is spread, the more value, but I would not say that just because it is not particularly widespread, that this is in and of itself a bad thing
12:34:26
schweers
I do think I see what you mean, I don’t think it is no problem at all, but I think it is blown out of proportion
12:35:48
schweers
I also wonder how this would play out if a large portion of our industry were to use (and appreciate) lisp
12:57:11
makomo
jcowan: the problem you describe is something i would attribute to lack of manpower and the size of the community
12:58:06
makomo
i'm not really sure. what other reason is there for not implementing 100% of the bindings?
13:00:07
makomo
jcowan: true i guess, but how is this connected to the fact that lisp normalizes arcane things, etc.?
13:00:46
jcowan
one of the examples from the original paper is "make C object oriented". This is so hard that it has only been done twice, and standardization on C++ and Objective-C has been fairly easy
13:01:18
jcowan
whereas "make Scheme object oriented" is a semester project, and so no OO system for Scheme has ever caught on; everyone rolls their own or does without
13:02:57
makomo
hm i see, it's not as easy to standardize on something as it is in other languages, when everyone can just invent their own
13:03:42
beach
jcowan: What is the lesson to be learned from "only half of CLOS was ever standardized"?
13:04:16
jcowan
lisp is the oldest language still in use, given that Fortran has changed almost beyond recognition
13:06:59
beach
jcowan: Furthermore, there is absolutely not reason to believe that the size of a library is proportional to the age of a language.
13:07:32
beach
jcowan: Good Common Lisp libraries would not run on LISP1.5, so they could not have been invented back then.
13:15:18
beach
jcowan: So I ask you again, what is the lesson to be learned from the fact that only half of CLOS was ever standardized?
13:16:24
beach
jcowan: Do you mean "all of it is so good that it should have been in the standard, but the people writing the standard for some reason did not do it"?
13:17:03
jcowan
makomo: I'm referring to the MOP. beach: Yes, except that it isn't "for some reason"
13:17:41
beach
jcowan: So you mean, anything invented by anybody should have been included in the standard, either fully or not at all?
13:18:53
beach
jcowan: Is it that CLOS MOP is what YOU would like to see included in the standard, so you lament the fact that it didn't happen?
13:19:17
jcowan
No, but it was part of the design from the beginning. What kept it out of the standard?
13:19:38
schweers
did MOP just come late to the party? The authors of The Art of the Metaobject Protocol seem to have CLOS sans MOP as a prerequisite
13:19:54
beach
jcowan: Oh, I can answer that. For good reasons, the committee did not find the MOP to be sufficiently well specified and the specification did not have good enough quality for the language specification.
13:20:29
beach
jcowan: The authors say something like "yeah, we know, this document is not good enough for a standard".
13:21:47
jcowan
rpg's article strongly suggests that the motives for rejecting it were rather more political than that, which makes the authors' remark quite likely to be an attempt to paper over a significant split in the community (also described by rpg)
13:22:21
beach
jcowan: OK, I now understand. YOU would have wanted the MOP to be in the standard, It isn't so now there is something wrong with the way the standard was created.
13:23:36
dim
svillemot: btw the SBCL stanza to add to ~/.sbclrc that we talked about looks like: (sb-ext:restrict-compiler-policy 'debug 3)
13:24:17
beach
jcowan: I apologize for that. I should have said something like "so the only way I can interpret your previous statement is as if YOU..."
13:35:32
tfb
jcowan: at the time CLOS was arriving in CL there were really serious worries that it could not be implemented efficiently on stock hardware. Those worries were even more serious if a MOP was added: it is a long time since I read AMOP but I am not sure it provides an answer as to how slot access can be made really fast, for instance.
13:37:02
jcowan
In general I believe the strategy to be: optimize the common case (e.g. classes whose metaclass is standard-class)
13:38:27
jcowan
Not different in principle from JIT compilation, or noticing that a generic-math procedure (like +, not in the sense of generic functions) is actually being used only to add fixnums and implementing it that way
13:42:19
tfb
Yes of course: the question is does the AMOP MOP (as it existed in 1989 or whenever the cutoff date was) let you do that portably (with the things people knew how to do in 1989 -- remember that lots of people still believed that the right answer was HW still).
13:44:17
tfb
I think the right answer was 'punt until the next standard because we need to get this thing out of the door': no-one knew there would not be a next standard for a quarter of a century!
13:59:00
jcowan
rpg says (again, I have no ax to grind here) that delaying the MOP was probably a good idea, as it was still too implementation-centric; of course, nobody foresaw the collapse of CL standardization.
14:01:35
tfb
yes, he's right (remember he was behind one of the stock-hardware lisps): it was a good idea as it was not ready (my opinion of course, but I didn't know anyone who thought it was ready in my corner of the community)
14:12:50
tfb
there was another tfb who was a cll person too (Thomas Burdick?) but I both tfb and when I can't get that tfeb
14:17:35
jcowan
at one time on another freenode channel there was a huge fad for 3LNs; since I was the only one with a 6LN, my lines stood out like a sore thumb
14:18:47
tfb
Serious question though: are there any non-spammy Lisp fora now which are not this one or reddit (which I am in recovery from)
14:19:55
jcowan
if you mean completely spam-free, probably not, but c.l.l. is not very spammy except for MY USERNAME IS THE SAME AS MY SUBJECT LINE guy.
14:21:29
tfb
jcowan: tha ks perhaps I will look at cll again if I can find a newsreader (or remember how gnus works)
14:24:10
schweers
do any of you folks employ any technique to remove string literals (or any larger literal values) from your source code? My main motivation is in order to avoid having to deal with linebreaks and indentation in the string literals. But I also like the idea of having all relevant strings in one place.
14:24:58
jcowan
point it at https://groups.google.com/group/comp.lang.lisp/feed/rss_v2_0_msgs.xml?num=50
14:29:34
rme
Is that obsessive-compulsive poster still there posting his unasked-for solutions to various questions in whatever programming language he is interested in at the time?
14:33:16
loke
I honestly have to admire, in some sick way, his ability to keep up that nonsense. He must spend a ridiculous amout of time doing this, and to do it for years.
14:35:25
loke
shrdlu68: If it's a bot, I'd be very surprised, and impressed. Also, I just decided to check the current state and one of his drecent posts is actually a correction for a bug in a previous post.
15:57:43
jcowan
adlai, tfb: Technically no, the ANSI standard wasn't published until 1994, so only 24 years ago
16:57:12
dim
last I had a look at it, it seemed to me that cl21 was attempting to provide solutions to things that are not a problem...
17:01:56
tfb
It seems to me that, if there were to be another standard, the things to concentrate on would be things that can't be simply done in portable CL
17:13:02
dim
unicode, sockets/network, threading and dynamic environments and IPC, maybe some more advanced app building blocks such as a reference HTTP cient and server, and I would love to have a pure-CL secure socket (TLS?) but I wonder if that's material for a standard...
17:14:24
borei
I have some generic question, not neccessary related directly to lisp, but rather to the programming overall. So i have program, there are several objects that are evolved based on program logic, actually there are a lot of object. I need to track object "version", so if one object is updated, objects related on it will be updated as well. Introducing "version" parameter for each object should solve propblem up to certain level, but i thin
17:16:49
tfb
borei: you probably want a dependency protocol such that objects know their dependents and updates get propagated through the graph
17:18:12
borei
so it's sort of sparce matrix where i can track "version" of the links between related objects ?
17:21:14
tfb
The CLOS MOP has an example of such a thing although it is slightly special-purpose (and I know there's a copy of the right chapter online but I can't find it now)
18:06:15
drunk_foxx[m]
Guys, is anyone here familiar with the University of Oslo course in Algorithms for AI and NLP, featuring Common Lisp? It's listed on Cliki, and I wonder is it worth taking, so asking for opinions
18:11:31
makomo
drunk_foxx[m]: i've skimmed the 2 videos where they introduce common lisp but that's all
18:11:55
makomo
it's the basic introduction to CL. i'm not sure how they use CL later on in the course itself
19:29:48
stacksmith
Is there a way to query current ASDF system name, suitable for asdf:system-relative-pathname?
19:31:37
Shinmera
If you mean the system of your own project, well, you better know the name yourself.
19:31:57
phoe
you got the dependencies wrong. your code *knows* what system it is in if it's ASDF-loaded.
19:32:05
Shinmera
If you mean the system that's being operated on during load, there's no way to get it outside of the individual perform calls, if I remember correctly.
19:32:33
phoe
because your ASD file explicitly declares to load that file. therefore there's a 1-to-N mapping between ASD system and a file.
19:32:43
Shinmera
Eh, actually, I suppose you can traverse the component tree to the root to get the system from inner perform calls.
19:33:44
stacksmith
Agreed. However, I just spent 20 minutes tracking down a stupid bug after renaming a system - it loaded fonts from a wrong directory...
19:35:19
stacksmith
So I am just trying to find the path to the system that was loaded, until I figure out a more rigorous way to maintain resources...
19:37:17
Shinmera
For paths relative to your sources I prefer to figure out the directory without ASDF by using something like: (defvar *here* #.(make-pathname :name NIL :type NIL :defaults (or *compile-file-pathname* *load-pathname* (error "Compile or load this file."))))
19:37:27
stacksmith
It seemed that declaring a global to hold the system name is more wrong than querying ASDF, - it obviously has it somewhere.
19:49:15
stacksmith
I think my issue is this: If I want to change the system name, say because I have a few versions I need to keep around (during development), I have to change the .asd file, the contents of the .asd file, and the directory name. Going through source looking for symbols that match the name seems just wrong. Am I being foolish or grossly missing the point?
19:49:19
phoe
I remember that #lispgames had some resources for that, because they use external assets a lot and have to bundle them into an executable when they buildops
19:50:33
phoe
then you change the name of FOO to FRED, and you need to update foo.asd (change system name and file name), and bar.asd and baz.asd (change dependency name)
19:51:52
stacksmith
phoe: I don't even have dependent system - I am just trying to keep foo1 and foo2 around. However I was loading data from a path relative to where 'foo lived.
20:06:59
phoe
and in other files use (asdf:system-relative-pathname :foo.resources "bar/baz/quux.jpg")
20:07:12
stacksmith
I just copied the directory with my old system, giving it a new name. Then, I had to change the asdf file name and contents, to avoid clashing with the old system. I thought that's enough for a quick and dirty way to try something new with the old system around. Then, I realized that there are hardwired references to system name, which I thought could be abstracted by querying ASDF.
20:07:43
stacksmith
I haven't thought about defining a separate system for resources... That would work.
21:23:32
jack_rabbit
Does anyone know what's up with the development of quicklisp? The client doesn't seem to have any commits on github in > 1 year, yet issues are being resolved. Are they keeping the working repo somewhere else?
21:29:10
aeth
jack_rabbit: If you're talking about quicklisp-client, it looks like the resolved issues aren't resolved through patches to quicklisp-client itself. https://github.com/quicklisp/quicklisp-client/issues?q=is%3Aissue+is%3Aclosed
21:32:34
jack_rabbit
I see. I should have looked more closely. I guess I was mostly surprised that there were no commits in the last year, but "if it ain't broke..."
22:44:36
sea
(time (loop for i in l)) and (time (loop for j being the elements of v)), where v and l are a vector and a list, both with the same number of elements (same elements, in fact)
22:46:08
sea
I don't think that's it, because then the results would be backwards. The vector has better locality and branch prediction
22:46:18
aeth
In general, vector operations will be *faster*, especially if the complete type (which includes the length!) is known.
22:49:22
sea
Okay so I changed it to 'across' instead of 'being the elements of'. It's much faster now, but the vector loop is still slower, by a factor of..4
22:50:18
aeth
(defun foo (v) (loop for j being the elements of v do (print j))) (defun bar (v) (loop for j being the elements of v do (print j))) (let ((l (list 1 2 3 4 5))) (time (foo l))) (let ((v (vector 1 2 3 4 5))) (time (bar v)))
22:50:57
aeth
When testing this sort of thing, (1) always define a function and (2) always initialize the outside data structure outside of the time
22:51:24
sea
(let ((v (coerce (iota k) 'vector)) (l (iota k))) (time (loop for i in l)) (time (loop for j across v)))
22:53:45
aeth
okay: (defun foo (l) (loop for i in l do (format nil "~D " i))) (defun bar (v) (loop for j being the elements of v do (format nil "~D " j))) (let ((l (iota 100000))) (time (foo l))) (let ((v (coerce (iota 100000) 'vector))) (time (bar v)))
22:54:18
sea
When I switched to your code, and took out the print, I had to use k = 1,000,000 before the difference showed up. The vector one is half as fast
22:58:14
sea
bar is slower in the profiler. 0.380999 sec/call, compared to 0.354999 sec/call for foo
22:59:57
aeth
The trick might be to find something that generates less garbage but that isn't optimized away
23:01:29
sea
Hrm, ran it in reverse order. The times are much closer, but bar still spends more time in the GC
23:03:59
aeth
This removes garbage... and the vector loses a lot. (I used do just to keep it consistent.)
23:04:02
aeth
(defun foo (l) (let ((sum 0)) (loop for i in l do (incf sum i)) sum)) (defun bar (v) (let ((sum 0)) (loop for j being the elements of v do (incf sum j)) sum)) (let ((l (iota 100000))) (time (foo l))) (let ((v (coerce (iota 100000) 'simple-vector))) (time (bar v)))
23:05:31
aeth
This gets the vector to win: (defun foo (l) (let ((sum 0)) (loop for i in l do (incf sum i)) sum)) (defun bar (v) (declare ((simple-array fixnum (100000)) v)) (let ((sum 0)) (loop for j across v do (incf sum j)) sum)) (let ((l (iota 100000))) (time (foo l))) (let ((v (coerce (iota 100000) '(simple-array fixnum (100000))))) (time (bar v)))
23:08:15
sea
I think so. I took that off. Now I'm running with: (declaim (optimize (debug 0) (speed 3) (space 0)))
23:08:32
aeth
(defun foo (l) (let ((sum 0)) (loop for i in l do (incf sum i)) sum)) (defun bar (v) (declare (optimize (speed 3) (debug 1)) ((simple-array fixnum (*)) v)) (let ((sum 0)) (loop for j across v do (incf sum j)) sum)) (let ((l (iota 100000))) (time (foo l))) (let ((v (coerce (iota 100000) '(simple-array fixnum (*))))) (time (bar v)))
23:08:53
sea
837,554 processor cycles vs 6,534,470 processor cycles and this time, it takes 8x as long!
23:16:25
jack_rabbit
For me, list took 4,695,880 processor cycles, vector took 722,763 processor cycles
23:17:23
jcowan
cdr-coded lists would help in this situation, but not enough overall for anyone to implement them any more
23:22:03
sea
I tried disassemble on both foo and bar but they're exactly the same as far as I can tell
23:22:41
aeth
Well, first make sure that they're not the sb-profile wrapper. You might have to (sb-profile:unprofile) before disassembling now
23:23:24
aeth
Same basic structure of generic-+, but the actual surroundings reflect iterating over their respective types
23:24:58
aeth
My latest bar has this: (declare (optimize (speed 3) (debug 1)) ((simple-array fixnum (*)) v))
23:26:50
aeth
Generic sequence and number code is almost always going to lose to specific sequence and number code in performance. They're basically the only two areas where type declarations are very useful for performance ime.
23:27:04
jack_rabbit
It doesn't matter the data type if the code iterating through it is for generic sequences.
23:27:22
sea
I need to alter the coerce as well. How do I coerce something to be a simple array of fixnums?
23:27:27
aeth
jack_rabbit: but my SBCL still optimizes bar once it knows that it is a simple-array fixnum (*)
23:28:15
aeth
sea: If it can only hold something of one non-T type, it's going to be a different thing than something that holds something of T
23:29:27
aeth
You win twice with an array type like I just gave (three times if a length is given): (1) it knows it's a certain kind of sequence and (2) it can infer what type the items are, which usually cannot be done
23:30:19
aeth
Unfortunately, this only applies to a small number of things. Portably just bit and character. Non-portably, a bunch of other numeric types like (almost always) single-float and (unsigned-byte 8) and fixnum
23:31:54
aeth
An array with an element-type should almost always be the most performant kind of sequence (or data structure in general) in Common Lisp. It will even beat lists at some things that lists are supposed to be better at.
23:32:45
sea
That's how I discovered this in the first place. I was timing an 'optimized' program, and found it got slower
23:34:20
sea
and the thing is that along with the time: 445,976 processor cycles , 4,636,812 processor cycles I get a tonne of time results printed as well, and they all basically look like this. The vector one is much larger
23:36:13
sea
Okay, restarted and re-evaluated what I had in the paste before. 0.148 seconds for bar, and 0.014 seconds for foo
23:39:24
pierpa
arrays with an element-type are not necessarily more performant than arrays with generic element types. It depends on what/when/how much the elements needs unboxing and reboxing.