freenode/#lisp - IRC Chatlog
Search
18:47:54
pjb
Getting correct results, and getting them safely, should be the only concern that should matter.
18:48:57
aeth
pjb: I'd say Meltdown/Spectre makes optimizing compilers like SBCL *more* important because the "free" hardware speedups can't be relied on if the price is security.
18:50:14
Bike
what i'm wondering about is, foreign-alloc has a compiler macro that works if the type is constant and the count is constant or not provided and nothing else is provided
18:50:43
Bike
hypothetically, if both are constant and :initial-contents is provided, it could still skip a runtime foreign-type-size and fill up the thing in a loop (maybe with a memcpy kind of function)
18:51:17
Bike
i thought i remembered someone complaining about this before, but it's not on the tracker that i can see
18:53:44
p_l
pjb: Meltdown had, IMO, more in common with Intel internal management practices than with optimising for C
18:54:07
aeth
I think the 2020s is the decade when we have to rely on software to get the continuous performance improvements that we all expect in computing. I wouldn't be surprised if single-threaded hardware gets only 3x or 4x faster in 2030 vs. 2020.
18:54:28
pjb
If they weren't racing for speed, but for safetly, they'd implement a lisp machine processor.
18:56:38
p_l
pjb: it got lost in the deluge of claims about C being responsible, but it was cost-cutting at Intel that led (at least partially) to current state
18:57:44
p_l
I'd argue that part of why CL can get significant optimisation gains (and Java already does) is that it isn't hobbled by C's "emulate PDP-11" model which is only made performant by putting a shitton of undefined behaviour
18:57:50
aeth
p_l: Can you blame them for cost cutting if each process node is exponentially more expensive? 7 nm will only have a handful of companies. I wonder if by 5 nm we'll have one or two.
18:59:05
p_l
and from time to time there were voices about letting the cpus return erroneous values for speed
18:59:25
p_l
aeth: there's even a lisp story in all of that, though I do not know if AMD still uses ACL2
18:59:47
aeth
p_l: On the other hand, CL does have a lot of mutability, including mutable dynamic global variables! So it has its own performance challenges.
19:06:53
p_l
(especially when you deal with things like the new 4-die threadrippers, which have significant differences between NUMA zones)
19:08:54
aeth
ah, okay. There's quite a name conflict with that acronym. https://en.wikipedia.org/wiki/CSP#Computing
19:28:42
Timzi
what does the #| |# notation mean in CL? Seems like it runs shell code, but I'm having issues searching for docs
19:32:36
aeth
It's uncommon because usually people use their tools to comment out multiple lines, e.g. M-x comment-region in emacs. And that uses the more common ;; line comment.
19:33:09
Timzi
so when it has bash commands inside that's just the shell reading through and executing what it finds?
19:35:21
aeth
#| is seen as a line comment to bash and a block comment to CL, so bash skips that line and CL skips until |#
19:47:41
pjb
Timzi: and more on-topic: https://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/intersection-r5rs-common-lisp-emacs-lisp/index.html
19:51:39
Timzi
the lisp one is neat too, might be worth switching to clisp just for the command line launcher lol
20:27:25
jmercouris
let's say I have a list of 12 elements, how can I iterate through it 4 elements at a time?
20:31:13
jmercouris
it just seems convoluted, I would look at the code later and wonder, why is it jumping by 4 cons cells??
20:31:47
trittweiler
jmercouris, I usually use (let ((the-list ...)) (loop while the-list for a = (pop the-list) for b = (pop the list) ... ) you can play with the exit condition depending how you want to deal with a list of length that is not a multiple of 4
20:32:31
Bike
(loop for (a b c d) on '(1 2 3 4 3 3 3 3 1 2 1 2) by #'cddddr collect (+ a b c d)) => (10 12 6), is that not what you want?
20:36:42
pjb
(loop for 4elems in (com.informatimago.common-lisp.cesarum.sequence:group-by (iota 22) 4) collect 4elems) #| --> ((0 1 2 3) (4 5 6 7) (8 9 10 11) (12 13 14 15) (16 17 18 19) (20 21)) |#
20:40:43
pjb
_death: probably you will do something else than collect; Here collect is to show what's bound to 4elems.
20:55:23
makomo
is it possible to use slime's in-place expansion features to expand local macros such as macrolets?
21:00:21
phoe
with cursor on the last "foo" I get the correct expansion, (macrolet ((foo (x) `(+ 2 ,x))) (+ 2 2))
21:07:35
makomo
hmm, i'll have to check out all of the different macroexpansion functions slime provides
21:33:49
trittweiler
jmercouris, See pop-n at https://pastebin.com/PQHv4YJU - this will destructively modify the input and not cons
21:38:02
trittweiler
it goes through the list twice, though. Should store (nthcdr (1- ,num) ,old-head) in a variable tmp, then bind ,new-head to (cdr ,tmp) and change the setf down there to (setf (cdr ,tmp) nil)
21:41:15
makomo
this library i found today has some cool ones if you want to take a look and have some fun: https://www.hexstreamsoft.com/libraries/place-utils
21:43:24
makomo
phoe: seems like "macrostep" is the package i'm looking for (and the SLIME contrib which uses it, called slime-macrostep)
21:43:49
makomo
slime can do it by itself, but only if you use one of the *-all variants and by placing your point on the whole macrolet form
22:33:39
it3ration
I don't spose there are current bindings to vulcan / osx metal / et al for Common Lisp
22:42:34
aeth
it3ration: You probably don't want to use Metal. Just use a Foo->Metal wrapper like https://moltengl.com/moltenvk/
22:43:12
aeth
it3ration: As far as Vulkan goes, there's https://github.com/3b/cl-vulkan/ but it's incomplete because most people just use OpenGL via https://github.com/3b/cl-opengl/
22:43:31
aeth
For Vulkan's added performance to matter and be worth it (in exchange for added complexity) you need a very large application.
22:43:33
makomo
AeroNotix: WITH-RESOLVED-PLACES is also pretty cool, because it's basically ONCE-ONLY but for places -- it solves the multiple evaluation problem for subforms of a place
22:45:55
makomo
check out the example: https://www.hexstreamsoft.com/libraries/place-utils/#with-resolved-places
22:46:40
Bike
j`ey: usually we write loops so that continue isn't necessary- move conditions out, that kind of thing
23:09:53
AeroNotix
makomo: so glad I found this library! There are a few macros I wanted to write myself but couldn't be bothered ;)
23:23:19
phoe
this evening I have a functioning Qtools interface to its modernized and bugfixed version
0:30:18
makomo
Bike: on a second thought, WITH-RESOLVED-PLACES isn't exactly like ONCE-ONLY. the typical use case would be wanting to avoid multiple evaluation of subforms of a place within a macro -- for that you would use WITH-RESOLVED-PLACES within the expansion but with a gensym'd name for the binding
0:31:50
makomo
a place version of ONCE-ONLY would use WITH-RESOLVED-PLACES for you so you don't have to. in essence, WITH-RESOLVED-PLACES is like the LET within the final expansion -- the one that does the evaluation
0:32:07
makomo
i've created PLACE-ONLY, which automates that work: http://plaster.tymoon.eu/view/905#905 :-D
0:33:38
makomo
(...) like the LET at the beginning of the final expansion of a macro that uses ONCE-ONLY*
0:35:33
makomo
PLACE-ONLY and ONCE-ONLY have a lot in common. perhaps another higher-order macro should be made to avoid code duplication -- triple backquotes? :^)
0:38:12
AeroNotix
I'm surprised a lot of these weren't included in the standard. Especially things like updatef/applyf
0:41:33
makomo
true. it's also amazing how the setf expander machinery even allows you to design stuff like this today, a couple of decades afterwards
0:49:40
makomo
UPDATEF is almost like FUNCALLF, except that it doesn't take any extra arguments but allows multiple place-function pairs instead
1:20:14
makomo
are there any tricks to COND-like macros that would allow me to reuse certain variables from a COND clause's test-form?
1:20:34
makomo
for example, in order to test for a case i need to do an exepensive computation but also reuse it later on within the body of the clause
1:51:44
makomo
PuercoPop: unfortunately that introduces bindings which are visible to all of the clauses
1:54:18
makomo
COND-LET is found within "serapeum" https://github.com/ruricolist/serapeum/blob/master/control-flow.lisp#L338
1:54:42
aeth
Bike: but now it's time for a second-order pun, i.e. utility library for Common Lisp named after an ancient city because alexandria is
1:55:07
aeth
Bike: so even though there is no notable great library of Carthage, the name Carthage would be a fitting name for a utility library because alexandria is so notable
1:56:06
aeth
It actually got rebuilt and was one of the major cities of the Roman Empire. It would make a good name for a utility library because both Alexandria and Carthage were major Roman cities in Africa
1:58:40
aeth
Rome, Antioch, Carthage, Constantinople, etc. would make good names for CL utility libraries because Alexandria exists. Except, of course, if you called your library Rome it better be the best utility library in history.
2:01:11
makomo
hm, i'm wondering whether it's possible to create a "conditional place". it would be named IFF and would be used like (IFF cond then-place else-place)
2:02:10
makomo
the expander for IFF can do some merging of the expansions for the two places, but i'm not sure how to avoid multiple evaluations of cond
2:02:44
makomo
it would have to happen outside all of the expressions produced by the setf expander :^(
3:54:53
p_l
is it maybe the land of strong static types and dynamic scope for all practical purpose?
4:11:36
Fare
The types are often a big burden, but they do come with nice benefits when you learn to go with them.
4:15:24
ealfonso`
what is a recommended resource for CL best practices, like how to organize a project into packages, formatting conventions, linter?
4:24:55
ealfonso`
I wanted to factor out a youtube data api client library currently embedded into another project
4:27:13
beach
ealfonso`: I don't think there are any general guidelines. I use an ASDF file and a package file for each "module".
4:29:25
beach
ealfonso`: If you want an example, I am pretty proud of Cluffer: https://github.com/robert-strandh/Cluffer
4:30:48
beach
ealfonso`: It also contains tests using my favorite testing technique (random test against a reference implementation), and documentation.
4:37:00
aeth
ealfonso`: the three styles are generally one-package-per-file (sometimes combined with package inferred system), one-package-per-directory, and one-package and everything top level. The latter two are the more popular styles.
4:39:37
aeth
ealfonso`: The compiler usually fills the role of the linter. Indentation is usually enforced by the editor, which is usually Emacs.
4:40:46
ealfonso`
I can look at a project like hunchentoot or beach's recommendation Cluffer as guidance. aeth that makes sense
4:41:22
loke
ealfonso: there are multiple packages conventions. My recommendation is that you create a single package for your project, and never IMPORT (or :USE) any packages. Always refer to symbols in other packages by a full PACKAGE:SYMBOL name. THat will reduce any problems.
4:43:04
buffergn0me
Random tests against reference implementation is such an awesome thing to do whenever you can
4:43:16
beach
loke: Why a single package? I think that depends on the size of the project. Even for a modest-size project like Cluffer, I have 8 packages so that each "module" only exports its protocol.
4:44:06
beach
buffergn0me: It is very powerful, yes, and it saves a lot of time trying to enumerate all test cases manually.
4:44:51
beach
Right. I always prefix my package names and ASDF system definitions. Like in SICL, they are all named sicl-* and in Cluffer, they are all named cluffer-*
4:46:09
aeth
Iirc the style ASDF/UIOP prefers is foo/bar rather than foo-bar. So if the package represents the directory bar for the project foo, it would be foo/bar.
4:46:12
buffergn0me
Parenscript had a package named "JS" for a long time. Well of course JavaScript came out and also had a package named "JS"
4:46:19
loke
beach: Because one has to have a reasonably deep understanding of packages to make that work. Packages are actually quite difficult to understand for beginners, even though the concept is actually remarkably simple.
4:47:07
buffergn0me
Glad I got rid of "JS" from Parenscript, still feeling bad about having a "PS" package though
4:50:07
buffergn0me
Also don't forget about the Java-style naming convention for packages. Another option
4:50:37
loke
buffergn0me: without package nicknames (not supported by all implementations) java-style packages are horrible.
4:50:41
beach
One neat trick is to do what Common Lisp itself does and also CLIM. There is one package that contains only the symbols that are exported. Then there are potentially several "implementation packages" that provide the real definitions of those symbols. But any symbols naming helper functions, helper classes, etc., are strictly private to the implementation packages.
4:51:45
beach
That way, the "implementation packages" are totally independent and can be maintained separately without any risk of stepping on helper symbols in other implementation packages.
4:53:10
beach
So in SICL, to name an example, I have packages like sicl-clos, sicl-boot sicl-reader, sicl-printer, sicl-loop, sicl-format, etc.
4:54:02
loke
beach: with multiple backend “private” packages there is the question about which “private” sumbols should be exported though
4:54:33
loke
Because there is no way you can make a private package, well, “private”. That means that any exported symbols from a private package becomes candidates in code completion.
4:55:06
loke
I have resorted to using :: when having cross-package references between private packages. It's not ideal.
4:55:28
loke
CLIM works around it by having almost everything stuffed intop a single clim-itnernals package.
4:55:48
beach
Like in sicl-loop, I export symbols that allow for customization of the LOOP expansion.
4:56:04
loke
beach: True, no rule. but... once they are exported, they end up being proposed in the symbol-completion of SLIME
4:56:55
loke
beach: But what if I have two private packages, let's call then FOO and BAR... Now I have some functions in FOO that BAR should see, but they should never be exposed to regular users.
4:56:59
beach
The CLIM solution with a single implementation package is not ideal, because it defeats the independence I was referring to.
4:58:28
loke
beach: right. that's pretty much the point I was trying to make; the package system could be better.
4:59:17
loke
If only the implementations I use supported it... That's currently SBCL, ABCL and ECL (and sometimes CCL)
4:59:21
beach
"<bla> is not good in Common Lisp. We need an improved standard! Why did the creators of Common Lisp not think about that?"
5:00:40
beach
All I can hope for is that, once SICL exists, some of the techniques I use will be also be used by other implementations.
5:00:42
loke
beach: I know. I was just lamenting the fact that implementations are not following your lead here.
5:01:18
beach
loke: It would require some significant work, so I can understand why they would be reluctant.
5:02:14
beach
loke: Using my fast generic dispatch might make it more practical to use generic functions, so that the implementation is more modular. That, too, will require a lot of work in existing implementations.
5:08:12
beach
The fundamental problem is that existing implementations are not very modular. Fundamental implementation decisions are scattered all over the code, as opposed to being isolated in separate modules. Therefore, changing one of those decisions requires looking at a large part of the code.
5:09:50
beach
Plus, for bootstrapping reasons, some code might be written in a subset of Common Lisp, like the compiler not using generic functions, for instance. Such restrictions make it very hard to work on the internals.
5:54:58
jackdaniel
recently on cl-pro mailing list there was a suggestion, that dividing software into multiple packages gets in a way of the programmer
5:55:41
jackdaniel
I don't have a strong opinion on that topic, but there certainly is a merit in a claim, that juggling packages may be tedious and confusing (i.e answering the question "what is where?")
5:57:00
jackdaniel
loke: chaotic development (i.e without a centralized "lead") has some profound qualities, i.e it is more reisistant for mistakes and it grows in many different (competing) directions
5:57:18
jackdaniel
then you are able to "pick" something what suits you best, or there may raise a consensus what is "the right choice"
6:20:05
buffergn0me
Another thing to consider is breaking up packages along domain specific language boundaries.
6:38:51
aeth
jackdaniel: I :USE internally even though USE in general is discouraged, so that gets around the major inconvenience of separate packages.
6:43:03
aeth
I have some macros that greatly cut down on exports. It's mostly just the one macro for defining with-foo-accessors. (with-foo-accessors ((foo foo) (bar bar)) ...) behaves like with-accessors, except it will intern and prefix the accessor, so it's really (with-accessors ((foo foobar::my-foo-foo) (bar foobar::my-foo-bar)) ...)