libera/#commonlisp - IRC Chatlog
Search
10:00:23
flip214
of course, if I knew how many levels deep the sublists go (yeah, so more like a tree), I could use ~{ ~}. In fact, I already do, for one level ;)
10:31:14
beach
Shinmera: As you know, I object to the term "compiled language", but I can understand that you may have to simplify things, given the audience.
10:32:52
beach
Shinmera: "We explore... games in detail" sounds like "in detail" refers to the games. Maybe "We explore in detail ... games"
10:34:15
beach
Shinmera: "In CLOS methods ..." looks like "methods" are attached to CLOS. I would insert a comma: "In CLOS, methods ...".
10:37:04
beach
Shinmera: "All of the methods require" I would write as "Each of the methods requires".
10:40:50
susam
Hello beach! That other nick (sp) is just my other nick connected via Matrix bridge. I was just testing out the Matrix-Libera bridging.
10:45:50
beach
Shinmera: My (admittedly small) family says that demonstrative pronouns should be followed by a noun phrase. "To implement this [...], "
10:46:55
beach
Shinmera: "to the enemy class' superclass list" -> "to the list of superclasses of the enemy class"
10:47:40
beach
Shinmera: "when determining the set of" is a dangling participle that many people don't like. "when the set of ... is determined".
10:49:59
beach
"when segregating behaviours" [also a dangling participle] "when behaviors are segregated"
10:53:48
beach
Shinmera: "when handled, the condition causes the stack to unwind", except that is not true. Handling a condition does not cause the stack to unwind.
10:55:51
Shinmera
in this first section I'm talking about handler-case, as that's the construct analogous to try/catch in other languages. I then refine it to distinguish with handler-bind later.
10:56:11
beach
And it is not the handling that causes it. It's the non-local control transfer that is part of the macro HANDLER-CASE.
10:57:04
jackdaniel
fwiw I have a local utility handler-case* that executes the handler /before/ unwinding the stack (built on top of handler-bind)
11:10:43
madnificent_
Xach: Probably not the best time to say so, but with QuickLisp being down I realized I do appreciate it existing very much. It's been a game changer. There's something stopping me from adding things I need to it which I can't point my finger to so I'm sure it'll keep gaining momentum. Thank you.
16:02:12
beach
lisp123: No. Since it is APPEND, Z has to be copied, but that's not more inefficient than it would be to copy it in other situations.
16:02:16
Bike
the way that's usually implemented, it doesn't actually use append, and each z is only copied once
16:03:51
lisp123
https://ccrma.stanford.edu/CCRMA/Courses/AlgoComp/cm/doc/contrib/lispstyle.html --> Remember that append copies its arguments. Avoid using append inside a loop to add elements to the back of a list. Use the collect clause in loop, or push elements onto a list and then nreverse the list to return the original ordering.
16:04:24
Bike
that sounds like it's talking about doing (append list (list elem)) which is actually kind of dumb
16:05:15
lisp123
Thanks for confirming. I felt it was something like that but got threw off because it said use a collect clause in a loop so wasn't 100% sure if it also applied to an append clause in the loop macro
16:07:04
lisp123
Not sure if you have seen this, but I uncovered this yesterday, still have to read through it to see if any nuggets of historic information http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai//lang/lisp/faq/
16:38:27
pjb
lisp123: the problem I have with loop for x in y append z is not that it's inefficient, it is that it's implemented in a non-conforming way in all implementations! The standard says that it should be implemented as (apply (function append) y), which implies that all the x in y are copied BUT THE LAST one! But all implementations copy all the elements: https://termbin.com/pjyq
16:55:30
lisp123
pjb: what are the implications of not copying the last one? I saw that in the standard but didn't realise what it means. Does it mean less memory should be used? And if one changes the last element then the appended list also should change?
17:02:04
pjb
lisp123: in general, indeed, it doesn't mean much, only some memory is reused. But if you mutate the original lists, then the mutations on the last one will be reflected on the appended list. And properties such as: tailp ldiff will break.
17:02:36
_death
(let ((x (list 'some 'long 'list))) (prog1 (list (append '(easy to append a prefix to) x) (append '(or multiple prefixes for) x)) (setf (car x) 'any)))
17:03:58
lisp123
I see. The implementations should be held to account! I wonder if there was a specific discussion done on this during ANSI process (perhaps alluding to the same points you just mentioned)
17:04:09
pjb
tailp/ldiff can be used to represend circular lists without circularity; this is how prolog does it. So it may be important for some algorithms…
17:05:17
pjb
Now, I admit that the behavior of the implementations is valid; we may want to amend the standard on this point… But it's a formal non-conformity.
17:06:03
pjb
If only they documented it! Implementations are allowed to diverge (they become a superset of a subset of CL), but only if they document both the subset and the superset!
17:07:13
lisp123
Agree. I feel bad for someone who may have relied upon that point, assuming it was true
17:07:39
pjb
We would discuss this on cll; nowadays there doesn't remain much common place where all implementers can discuss those problems. We could make a lightning talk at next ELS…
17:20:19
copec
Do you still :use between separate lisp files that will make up a single system that will have the package name that should be used (via pln's). Or do you even pln between the separate lisp files (each file in its own "subpackage")?
17:35:45
Shinmera
Ah. I do not use one package per file as I think it's a horrible idea. I use plns a lot, and never :use a package unless it's specifically designed for that.
17:42:05
copec
Shinmera: For a project that you want to make a singular system, do you use a file for the defpackage form, for what you want to export, and then just in-package the same package the rest of the files, I take it?
17:44:00
Shinmera
To me packages are part of the user interface. As such, I make as many packages as I think is appropriate for the user. Typically this is one, but sometimes it is more. I put those into a package.lisp, and then use in-package as appropriate.
17:45:01
etimmons
I drank the whole package inferred system, one package per file kool aid a while ago, but have been souring on it as of late.
17:45:37
Shinmera
Files are part of the internal interface. They are an implementation detail that should serve to organise code how it makes sense to you, not to the user.
17:47:00
copec
I was hoping it would also cut along the aspect of making code more readable, since I was generally my-system-name/file-name for the package along each file
17:47:33
etimmons
I still think it has its merits in some circumstances, but I realized what I really liked about it was the ability to locally declare dependencies, on both other files internal to the same system and other systems.
17:48:38
etimmons
I started work on an ASDF extension that was basically package-inferred-system, but did not require one package per file.
17:49:13
etimmons
Sadly, I haven't had the time to go back and finish it yet now that some of the support it needed from ASDF has been exported
17:55:14
copec
selwyn, There is probably some limit in an arbitrary component to be reached with file length, but generally they are divided up according to how a programmer wants to organize, which ideally should fall a long lines most commonly understood
18:10:42
copec
One more question Shinmera: How do you quickly find in which file where a definition is for a symbol for a respective namespace is defined?
18:26:17
Shinmera
I can't really think of a situation where one really needs to know this but can't access emacs
18:27:53
Shinmera
sounds like a bad reason to force the entire code organisation into a specific style :v
19:20:38
pjb
selwyn: that said, when you browse C sources where there's one function per file, you realize that it's going to far too.
19:22:54
White_Flame
forcing a linearization of your code, instead of being a set of declarations & scopes, and having more flexible organization in viewing & editing
19:25:29
copec
I currently divide stuff along lines of where there is a complete abstraction per-say, for instance: https://gist.github.com/copecog/99d4e34065ab1dac84524f0856cec8b4
19:27:05
White_Flame
pve: that's only one idea, but anything that doesn't lock you to the happenstance location in files is good
19:27:31
White_Flame
copec: abstractions overlap, and different functions/declarations have different relations, just not prev/next inside a section
19:30:08
pve
White_Flame: yeah, I think I saw on reddit that someone was working on a "class browser" type emacs mode (possibly integrated with slime).. it looked pretty interesting, but I'm not sure how serious it was
19:30:15
copec
Yeah, it usually becomes "there is too much going on in this single file", so the arbitrary spot that there are less specific details that are convenient to digest together, make the cut there and start a new file
19:30:41
ecraven
is there any short tutorial on how to read a binary file into some sort of sequence and then access it as various different number formats at given offsets? (u32le, u16be, and so on)
19:31:44
pjb
ecraven: (let ((data (binary-file-contents "/etc/passwd"))) (values (subseq data 0 10) (subseq data 80 90))) #| --> #(35 35 10 35 32 85 115 101 114 32) ; #(115 121 115 116 101 109 32 105 115 32) |#
19:31:48
copec
Then when all done, it becomes clear where it makes more sense to divide up, so I end up moving source around anyways. I have never seemed to have gotten enough experience to call that out ahead of time
19:32:03
pjb
ecraven: (let ((data (binary-file-contents "/etc/passwd" :element-type '(unsigned-byte 16)))) (values (subseq data 0 10) (subseq data 80 90))) #| --> #(8995 8970 21792 25971 8306 24900 24948 24930 25971 8970) ; #(26998 25956 8292 31074 8970 20256 25968 8302 26948 25970) |#
19:34:02
pjb
I don't know any implementation having a :external-format that let you specify that for binary file.
19:34:37
pjb
The standard says: The external-format is meaningful for any kind of file stream whose element type is a subtype of character.
19:43:49
White_Flame
I usually use MAP for that, although if you need extended features of LOOP like conditionall COLLECT, then yeah that's harder
19:44:59
White_Flame
if you don't care about GC pressure, you can always (coerce (loop .. ) '(vector ...))
19:46:11
White_Flame
if you need to do soemthing like that, I prefer (map (make-array size) (lambda () ...)) to generate them
19:49:08
copec
It's generally not CL style, but I pretty much always factor complicated loops into recursive algorithms, using function tail recursion, and under SBCL it has always been quicker too
20:56:37
copec
White_Flame, what kind of organizational system would you have in mind? Storing the code in some sort of DB under declarations & scopes?
21:06:23
pjb
copec: this could still be files, for compatibility with current tools (git, asdf, quicklisp).
21:07:34
pjb
copec: the heuristic would start with 1 package = 1 file, plus some topological sorting of dependencies (compilation-time and run-time), so eval-when or separate dependent files would be generated automatically.