libera/commonlisp - IRC Chatlog
Search
15:38:06
aeth
HN was always about startups... Lisp and programming-in-general content has gone down and complaining-about-housing-costs-in-SF has gone up as the bull market rallies for over a decade now.
15:49:45
_death
I found land of lisp entertaining, but I was not a newbie at the time, and I wouldn't recommend it to newbies
15:54:33
aeth
tyson2: well, my impression at the time, and it has been years, is that it seemed oudated.
15:56:25
aeth
my impression of PCL is that it doesn't seem... linear? I definitely read the chapters out of order as needed
15:57:48
tyson2
I decided not to try using PCL on windows, will install it in WSL (probably using Docker image), and develop from emacs on windows, which I'm comfortable with
16:11:15
etimmons
qhong: Since you referenced the discussion a few days ago, I'm guessing you're also interested in loading multiple versions of the same system into the same image? Perhaps even as part of the dependency tree of a single project?
16:11:27
etimmons
If so, I think your rename-package hack will also likely make generic functions way less useful.
16:11:50
etimmons
Let's assume there's a system (and package) FOO. It defines the class BAR and has a generic function BAZ with a method specialized on BAR.
16:12:05
etimmons
Then I have a system qux that somehow pulls in two different versions of FOO in its dependency tree. Let's say they're renamed to FOO@1 and FOO@2.
16:12:16
etimmons
Under the current practice, it'd be completely fine to share instances of BAR across different branches of the dependency tree.
16:12:32
etimmons
But if that happens with the rename-package hack, you'll likely end up calling FOO@2:BAZ on a FOO@1:BAR instance. No such method exists for that: boom.
16:15:08
etimmons
beach: I really need to read your paper on that. It's very interesting to me, but so far I've been inferring capabilities based on what other people are saying
16:16:10
beach
The only invention is the cell thing to make function calls as fast as in typical Common Lisp implementations.
16:16:17
qhong
etimmons: I'm still thinking about what reproducible mean under CL context. I think the problem stems from the absence of distinction between "software" and "config" in Lisp system. Different version of "software" should be definitely isolated, but maybe not so config. We may heuristically count all special variables and generic functions as configs.
16:16:44
etimmons
I guess my biggest question is how can different environments interact (if at all). That's not something I've been able to glean from listening to others
16:17:38
phoe
EdLangley[m]: the main issue with GENERIC-{FLET,LABELS} is the special operator CL:FUNCTION - we want it to return the GF itself, rather than some intermediate function that wraps over it (as would be the case with FBIND)
16:19:19
phoe
_death: https://www.reddit.com/r/lisp/comments/s1itqi/the_common_lisp_omnificent_gui_online_lisp/
16:19:39
phoe
tyson2: https://www.reddit.com/r/lisp/comments/s1itqi/the_common_lisp_omnificent_gui_online_lisp/
16:22:22
phoe
EdLangley[m]: it seems that a real GENERIC-FBIND trying to bind a function named FOO would need to bind a generic function object as some lexical variable #:FOO, then walk the body form and rewrite it in order to replace (FOO ...) calls with (FUNCALL #:FOO ...) and value occurrences of #'FOO with just #:FOO
16:22:49
phoe
and that's ugly but necessary if we want CL:FUNCTION to work correctly in that context
16:23:44
phoe
either that, or get an implementation-defined FBIND, or use some kind of DEFGENERIC-with-an-anonymous-name trickeries like that post mentioned
16:41:49
Bike
i wonder if an fbind could be useful for other things. if not generic functions, some other kinds of funcallable instances.
16:45:29
phoe
but there isn't such a thing, AFAIK, and won't be because FBIND requires evaluation before a function is bound
16:45:53
phoe
the best there is is SERAPEUM:FBIND which does macrology and binding intermediate functions to work around this
16:47:14
phoe
OK, let me clarify: "won't be" as in "I have no idea if any implementer actually considers it worthy enough to implement it as a true special form"
16:50:39
Bike
guess it could be slightly complicated since now #'foo can mean something other than a known function or global lookup. probably not a huge deal though.
16:51:29
phoe
the whole point of it being a special form is it interacting with CL:FUNCTION the same way that CL:FLET and CL:LABELS do
16:51:58
phoe
how exactly its semantics are implemented is a bit more complex I guess, because you need to grab a function as a value and stuff it back into the function namespace
16:52:26
phoe
and unlike with FLET/LABELS you have no idea what kind of function object it is, you don't know its lambda list or type
16:52:51
phoe
I guess that can complicate a FBIND implementation, unless the programmer provides appropriate FTYPE declarations
16:53:43
phoe
like, (defun foo (fn) (fbind ((fn fn)) ...)) - inside the body we have no idea what #'FN is like or how to optimize it
16:56:48
phoe
like, a naïve version would be to rewrite FBIND into LET, FUNCTION of FBIND'd functions into variable references, and calls
16:59:05
Bike
oh i'm just thinking of how to do it as an implementor. if i wanted to try a userspace thing i'd probably just shadow cl:function and #' and call it good
16:59:34
phoe
I'd call it sorta ugly and actually rewrite the body instead, so I can keep the original cl:function and #'
17:02:15
Bike
i figure it would be fine since if you're using fbind you're already doing an extension thing, and also it's lexical, so the fbind user is also the one using the shadow #'
17:02:38
Bike
fbind would toss some information into symbol-macrolet, which the function macro would then use, and if there wasn't any fbind to the name it would just expand into cl:function
17:32:53
phoe
I supplied it as a dependency for a MIT library, and that's not a good thing licensing-wise
17:35:55
pl
qhong: people have issues understanding what GPL means for /C/, Lisp is probably exposing it even more :/
17:36:45
phoe
I guess it's same as elsewhere, you need to share source code for everything in your Lisp image when you deliver binaries containing GPL code, plus anti-tivoization clauses in case of GPLv3
17:39:43
phoe
I have no idea :D it probably uses the same mechanism that allows you to deliver GPLv3 code using proprietary compilers, e.g. MSVC or Intel for C/C++
17:40:37
phoe
yes, the main exercise here is that there's no good way to tell apart the code and the platform in image-based environments
17:42:12
foxfromabyss
I am trying to use https://github.com/fukamachi/websocket-driver, specifically the client part
17:42:12
foxfromabyss
But it fails with HTTP 400 being unexpected, regardless whether I target a remote, known-to-work, server, or the local server, done like the example in the repo suggests
17:44:16
random-nick
I think GPL has a section about system libraries, which is what allows you to compile with proprietary C compilers but I don't know if something like the entirety of lispworks counts as a system library for the GPL
17:45:16
dbotton
phoe I added a link in a comment on the lisp meeting to a small follow up video with a fully fleshed out builder including events, etc https://www.reddit.com/r/lisp/comments/sd9wf1/clog_builder_cl_web_3_awesome_lang_awesome_tool/
17:45:25
random-nick
I think it's more about the system libraries being interchangeable with free ones
17:45:53
phoe
random-nick: well, you can grab SBCL instead of LispWorks and deliver with that I guess
17:46:12
phoe
and you can grab the free implementations of these extensions too :D or write them if they don't exist
17:53:01
EdLangley[m]
Why wouldn't (let ((#1=#:foo (make-funcallable))) (flet ((foo (&rest args) (apply #1# args))) ....)) work?
18:07:42
Bike
EdLangley[m]: what i'm envisioning here is situations in which you want to do something with the instance other than call it.
18:09:52
White_Flame
dbotton: your URL included "web_3" and I was about to rail against that phrase ;)
18:11:41
Bike
that said, while i've probably defined more classes of functional instances than 99.9% of lispers, i've never really needed to lexically bind them.
18:14:02
Bike
partly that's probably because i'm using them within an implementation, though. people writing software software probably have different patterns
18:22:07
dbotton
White_Flame lol well nothing has changed on the web in a very long time, including people trying to hi jack names with version numbers
18:50:04
dbotton
shinmera as we I use to say in my corporate days - but it worked on my machine - ie don[t blame for human error ;)
18:53:20
Shinmera
Anyway, sure wish I had the money to hire another programmer so I could concentrate on, you know, actually designing stuff instead of fixing the myriad of bugs in my tower of yaks
19:11:37
dbotton
If I had the money I would hire a programmer to add the robustness needed that I get in other languages like Ada that don't come for free but you are forced to address from the start
19:18:39
Shinmera
For the scale of the kind of game I'm building I'm definitely way under-budgeted and under-staffed :/
19:53:49
lagash
foxfromabyss: make a sacrifice to the Goddess Fortuna, where you'll find the answer through a series of lightning bolts striking your house
22:53:45
phantomics
For all who are interested: I will be hosting a webinar on the April APL compiler (compiles APL into Common Lisp) tomorrow at 16:00 UTC. You can see the webinar at https://zoom.us/j/858532665, the passcode is 391680 It may be early for American viewers; that's 8am on the US west coast
22:54:43
phantomics
This webinar is hosted by the British APL Association, so it'll offer a look at April from the perspective of APL users, as opposed to my last presentation which was directed at Lisp users
0:34:29
samps
Hi folks. I've been working on some pet projects in Common Lisp. I'm using SBCL and Iḿ having trouble trying to understand a compilation error. Would anyone be able to help me out? https://gist.github.com/lsmag/ebb517a8702f454c4bbf624d7c44b182 ... I tried typing out roughly the same faulty line on the REPL and it seems to work
0:34:50
samps
changing the line just to (merge-pathnames (first argument)) also spawns the same error
0:36:53
samps
I've read about it but haven't dipped my toes into condition signalling yet, though I have found quite a few while playing with the adopt library
0:37:06
EdLangley[m]
Anyways, that's not an error it's a warning because write-line expects a string and it's getting a pathname
0:39:00
EdLangley[m]
samps: yeah, I'm just mentioning that because using the expected terminology helps people understand the problem :)
0:39:48
samps
damn, I was caught off guard. The signal message actually starts with `IN (WRITE-LINE ...)`. Thanks, folks :)
0:41:27
EdLangley[m]
I'm not sure, my guess is that just means sbcl able to print the form that's triggering the error for some reason
1:22:27
Xach
White_Flame: i seem to remember sbcl putting a finalizer on closing the fd on a fd-stream, but I'd have to double-check. I don't know if that would make it "typical" or not.
1:50:21
Bike
so thanks to mfiano nerd sniping me, i now know that sbcl actually does maintain backpointers from arrays to arrays displaced to them (sb-kernel:%array-displaced-from). however the general form of the with-array-data macro does still do a loop to get at the simple vector backing
1:50:21
Bike
(https://github.com/sbcl/sbcl/blob/master/src/compiler/array-tran.lisp#L1629-L1661). so does sbcl not actually collapse displacements despite going through some effort to maintain the backpointers?
1:53:44
EdLangley[m]
Is there any way to promise to the compiler that an argument to a function is const?
1:54:55
EdLangley[m]
e.g. if I have (defun mapping (fn) (lambda (list) (mapcar fn list))) It'd be nice if I could convince the compiler that it doesn't need a closure
1:57:30
EdLangley[m]
What I'm trying to figure out if there's anyway to use functions like this without blocking optimizations of things like (compose (mapping #'1+) (mapping #'1+))
1:58:35
EdLangley[m]
If the compiler assumes FN never changes, I'd think you could do some sort of inlining trick to avoid extra indirection.
2:01:19
EdLangley[m]
It should be able to replace (mapping #'1+) with (lambda (list) (mapcar #'1+ list))
2:01:40
Bike
if it's willing to believe that MAPPING will never be redefined, yeah. you could just proclaim it inline.
2:02:25
Bike
but MAPPING as a function itself can't behave as though its argument is unchanging, because it doesn't know what its argument is until it's called.
2:03:51
EdLangley[m]
It can't know that the value named by FN isn't mutated, but it can know that FN is never re-bound
2:06:28
mfiano
How would it eliminate it if calling thing function is the only way to bind it to a value?
2:07:19
EdLangley[m]
I think what I'm really interested in is whether something like (compose (mapping ...) (mapping ...)) can be optimized at all
2:08:41
Bike
so (compose (mapping #'1+) (mapping #'1+)) will end up as something like (let ((m1 (mapping #'1+)) (m2 (mapping #'1+))) (lambda (&rest args) (funcall m1 (apply m2 args))))
2:09:04
Bike
then after inlining each (mapping #'1+) ends up as (let ((fn #'1+)) (lambda (list) (mapcar fn list)))
2:10:21
Bike
that said, it will probably not be smart enough to avoid consing an intermediate list, due to side effect restrictions
2:11:18
EdLangley[m]
I've always wondered how much of an optimization barrier passing LAMBDAs around is
2:11:54
EdLangley[m]
And it sounds like compilers can, in theory at least, be smart enough to inline them like any other function
2:13:19
qhong
why not do the same for compiler, assume the best scenario, and update dependent if the assumption is broken
2:14:40
Bike
for avoiding consing up the intermediate list, i think what the compiler would have to do is observe that the first mapcar's result is only ever used by the second mapcar, so the storage can be reused
2:14:48
qhong
When lambda get passed around, most of the case that means they are stored in mutable variables that confuses compiler
2:15:11
Bike
i mean, sure, but in this case the variables aren't actually mutable, so it's pretty easy to see how it goes.
2:15:25
qhong
Bike: there's systematic western adhoc method called stream fusion, and chad Soviet method called super-compilation
2:16:34
qhong
Bike: yes I think the above cases the only problem is global functions getting redefined
2:17:26
sm2n
but more or less any nontrivial language does not necessarily reach a normal form in finite time
2:18:19
Bike
"I have interpreted the major steps in biological and cultural evolution, including the emergence of the thinking human being, as nothing else but metasystem transitions on a large scale. Even though my Ph.D. was in theoretical physics, I" and i'm out.
2:18:20
sm2n
with supercompilation you can get bit-identical compiler output for all programs with the same denotational semantics
2:19:21
qhong
sm2n: are we talking about the same thing? there're two totally different thing supercompilation and superoptimization which has confusing name
2:19:53
pillton
Bike: Have you seen work which allows users to perform optimisations of compositions (H X) <=> (G (F X)) without relying on compiler macros / inlining? I was thinking something like (LET ((GRAPH (G (F (LAZILY X))))) (OPTIMIZE-GRAPH GRAPH)) <=> (LAMBDA (X) (H X)).
2:21:09
Bike
seen some of that in the haskellverse, i think, though i don't think i understand your example.
2:30:52
pillton
Bike: Assume that the evaluation of (G (F X)) is equivalent to the evaluation of (H X). I could extend both F and G to support being able to "record" their operations in a graph structure when given an "lazy" object. A "lazy" object allows F to inspect the object to obtain its type but does not perform the operation. The function F returns another "lazy" object which allows G to record its operation in the same graph as F and
2:32:08
pillton
Bike: The function OPTIMIZE-GRAPH takes the full graph and identifies that #'H can be used instead of (compose #'G #'F) and returns the "optimized" graph as a closure.
2:35:20
Bike
okay, sure. seems pretty simple phrased like that. your graph is something like <input> -> F -> G -> <output>, your optimizer replaces F -> G with H.
2:41:13
pillton
Sorry, I think realistically, the output of OPTIMIZE-GRAPH would be (LAMBDA () (H X)).
3:27:15
yottabyte
if I'm reading lines from a file, and I see "^M" in my repl, that means newline, right? how do I check for equality for that? as in, how do I check the line is a newline?
3:36:43
White_Flame
CR = 13 = ^M, LF = 10 = ^J. "Newline" technically is LF, but in practice the output encoder will render it as whatever's default for the platform
3:37:31
White_Flame
well, ASCII calls LF Newline as well, afaik. I guess #\Newline is independent of that