libera/#commonlisp - IRC Chatlog
Search
8:36:31
cosimone
_death: yes, i noticed that too, if i run (documentation ...), i can still see the string
8:36:33
beach
mfiano: I just meant that I won't argue with you since you were not referring to any of my suggestions.
8:36:47
ecraven
beach: well, emacs *could* do this by just sending the form to swank for fontification
8:37:06
cosimone
it's up to personal preference, but i think the "canonical" form seems to be declarations first
8:40:16
ecraven
I've been thinking about that on and off, actually *parsing* s-expressions for fontification in emacs, not just regex-matching them
8:40:39
ecraven
and even better than parsing, using a running system to know *what* anything is actually
8:42:31
beach
ecraven: Second Climacs uses READ (in the form of Eclector) to parse the buffer contents, so that it can take custom reader macros and such into account. And scymtym has been doing work on syntax analysis of the result.
8:43:13
beach
ecraven: The main thing stopping me (or us) from making progress is that I still need to figure out how to compute indentation.
8:44:16
ecraven
for example, emacs "incorrectly" indents '(foo bar\nbaz quux), where I *want* foo and baz to start at the same column (because it's all "data").
8:44:56
beach
ecraven: But, again, to do it right, you need to parse the contents using Common Lisp READ.
8:46:00
mfiano
in an asdf:defsystem :depends-on form, if the first dependency is a symbol that begins with DEF, it indents the rest of the list very strangely. It also doesn't matter if its a symbol, keyword, or uninterned symbol prefix.
8:46:28
mfiano
I like to sort my dependencies lexicographically, and in one project #:defpackage-plus was first. Big mistake :)
8:47:04
_death
there is a discussion about precisely these indentation issues current on emacs-devel
8:47:58
jackdaniel
automatic indentation was supposed to save the programmer from certain cosmetic dillemas but given how much headache comes from invalid indentation (or of implementing the right thing), that claim seems to be shaky ,)
8:48:46
beach
jackdaniel: I maintain that the problems are due to a fundamentally flawed technique for computing indentation.
8:50:52
jackdaniel
beach: I know; I wonder what would be the correct approach for editors that aim to target multiple languages with indentation rules that depend on the role of a symbol
8:51:25
jackdaniel
probably such editor would need to implement at least a part of a compiler for each supported language
8:51:57
jackdaniel
(and this is more common in ides lately I think, not necessarily for indentation but for completion and such)
8:53:32
pjb
gin: you may start by reading AIM-8 http://informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/aim-8/aim-8.html ; and have a look at those examples: http://informatimago.com/articles/usenet.html#Compilation
8:53:59
pjb
gin: but then, if you want to go beyond the toy tiny lisp interpreter, reading LiSP is indeed a very good idea.
8:54:05
beach
jackdaniel: I seriously doubt that there is a uniform approach that can take different languages into account. Each language would need a parser that recognizes that language, in our case READ. And it needs to be incremental to handle large buffers, which I suspect is not even possible in most languages.
8:55:04
pjb
gin: and the latest edition of the Dragon Book, Compiler Principles Techniques and Tools, Aho et al. http://dragonbook.stanford.edu/ if you want to go beyond (other languages with parsers, code generation, the latest edition even covers some garbage collection).
8:57:16
pjb
gin: LiSP is 500 pages, but it describes actually 11 interpreters/compilers refining them from simplistic to sophisticated, so it's more like 11 times 45 pages. You can process 45 pages ;-)
8:57:59
beach
_death: Sure, but I suspect that for languages with complicated syntax rules, there will be many more cases where the entire buffer parse result will be invalidated by a single keystroke.
9:00:00
_death
beach: depends on the keystroke :).. but I think it seems to work in practice, so IDEs (and emacs..) adopt or experiment with it
9:00:13
mfiano
beach: tree-sitter is supposed to be fault tolerant for things like that, though i don't know how that works in process
9:35:22
flip214
when using FORMAT with ~s, can I make the output (nested in a sublist) of floats like with ~f instead of ~e? for this use case 123456789123.456 is easier to read/compare than 1.234…e9.
9:45:17
pjb
(format nil "(~{~F~^ ~})" '(123456789123.456 100000000.2 0.0000012345)) #| --> "(123456790000.0 100000000.0 0.0000012345)" |#
9:46:25
pjb
(setf *read-default-float-format* 'double-float) (format nil "(~{~F~^ ~})" '(123456789123.456 100000000.2 0.0000012345)) #| --> "(123456789123.456 100000000.2 0.0000012345)"" |#
9:47:43
loke[m]
"A declare expression, sometimes called a declaration, can occur only at the beginning of the bodies of certain forms; that is, it may be preceded only by other declare expressions, or by a documentation string if the context permits."
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