libera/#commonlisp - IRC Chatlog
Search
8:06:14
pve
Hi, is it stylistically ok to use strings in a defpackage form, e.g. (:export "CAT" "MEOW" "PURR" ...)?
8:12:06
beach
pve: I personally think it looks ugly if you then use lower-case letters in the code, which is why I use uninterned symbols instead.
8:14:23
beach
The other problem with strings is that it may not work when the readtable changes. If you use uninterned symbols, there is a better chance that the name of the symbol you use in code is going to be the same as that of the uninterned symbol. I am thinking particularly of Franz "modern mode".
8:18:06
pve
beach: Ok thanks. Now that I think about it, this might even be just a matter of syntax highlighting. I like how the strings stand out a bit among the keywords.
8:20:27
beach
pve: I have said this several times, but let me say it again: Emacs syntax highlighting is mediocre at best. It doesn't take different roles of symbols into account. It seems wrong to highlight all uninterned symbols the same no matter the role, and it seems wrong to highlight all strings the same too.
8:21:00
beach
pve: I use Emacs for Common Lisp programming only because we don't have anything better yet. But we are working on it.
8:23:28
JeromeLon
(let ((*message* *messages*)) (do something that indirectly (and temporarily) changes and uses *messages*))
8:23:56
JeromeLon
I remember getting an sbcl warning about this (using lexical variable for a name that looks like a dynamic one)
8:24:26
JeromeLon
But I am not getting it anymore. Does anyone have any idea what circumstances are triggering it?
8:24:46
beach
JeromeLon: It would be highly unusual to initialize a variable with a name in singular form with a variable in plural form.
8:25:18
pve
beach: Oh, are you saying that, for example, exported symbols in a defpackage form (written as uninterned symbols) could be highlighted differently than uninterned symbols elsewhere in the code?
8:26:03
beach
pve: And the strings used in the :EXPORT clause should be highlighted the same as the uninterned symbols in that clause.
8:26:50
cosimone
there are some emacs theems, such as dracula, that do highlight documentation strings differently with respect to other strings
8:27:08
cosimone
however, using a declare expression beforehand fools it into thinking it's a regular string
8:27:40
JeromeLon
beach: or maybe that was my mistake? yes, it was probably a typo, I can reproduce. Thanks!
8:28:20
beach
Nilby: Because, as I said, if the role is the same, the highlighting should be the same.
8:28:22
mfiano
I do not consider _that_ aspect of Emacs highlighting wrong. I wouldn't want it any other way
8:28:23
cosimone
i think a lot of the logic used to highlight common lisp is the same as the one used for emacs lisp, but i could be wrong
8:28:37
loke[m]
I'll have to check the spec, but I'm pretty sure that the declarations have to come after the docstring.
8:28:51
cosimone
i modified color-identifiers.el a bit to account for common lisp, it does provide a nicer and much richer highlighting
8:30:32
cosimone
loke[m]: according to http://www.lispworks.com/documentation/HyperSpec/Body/m_defun.htm#defun, declarations come before documentation
8:31:18
beach
mfiano: Do you think it is fine that 1. The first DEFMETHOD is highlighted as if it were an operator, and 2. that the second DEFMETHOD is not highlighted the same as the first?
8:31:43
mfiano
beach: I wasn't talking about semantic highlighting. I was talking about the atom type differentiations.
8:32:32
beach
mfiano: So in (defpackage ... (:export "FOO" 'bar) you want FOO and bar highlighted differently?
8:32:44
mfiano
I would make lots of mistakes if my uninterned symbol was the same color as a keyword symbol as an argument to a function for example.
8:34:02
beach
On the other hand, if you do (f :foo :foo) and F is (defun f (&key foo)...) I would definitely want the second :foo to be highlighted differently.
8:35:45
beach
I maintain that the role of a token is more important than its exact syntax. And I maintain that Emacs is unable to take the role into account.
8:35:53
mfiano
Why will you "refuse to make suggestions" and "be quiet" over different opinions? Lisp's main strengths include the flexibility it gives programmers and listening to other opinions is always welcome. That sounds sort of a childish response..
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