libera/commonlisp - IRC Chatlog
Search
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
3:56:03
remexre
are displaced vectors expensive to have as temporaries? wondering why e.g. find has :start, instead of there being a convenient (slice vec 3 nil) or something to make displaced vectors, and the common pattern being to use them
3:58:53
pillton
remexre: (slice vec 3 nil) requires consing the displaced array where (find ... :start 3) does not.
3:59:56
remexre
shouldn't a really basic escape analysis be able to determine that the one created by (find x (slice vec 3 nil)) has dynamic extent though?
4:02:15
remexre
pillton: this wouldn't be something declared on slice, it'd be something the compiler could recognize after inlining it
4:02:31
minion
remexre: look at universal greeting time: It is always morning when a person enters a channel, and late night when they leave. You may want to read http://www.total-knowledge.com/~ilya/mips/ugt.html for further information
4:05:41
pillton
remexre: Sure, but it wouldn't catch every case where (find vec :start 3) is trivial to define, doesn't cons, interacts easily with :from-end, and doesn't require a "sufficiently smart" compiler.