<smlckz>
What exactly is the dynamic scope or extent? What are some good resources you'd recommend to learn more about it?
<aeth>
dynamic-scope is the old-style, runtime (rather than compile-time "lexical") scoping rules, which is primarily useful for things like streams and mainly shows up in streams and in globals, but you can even do it locally like ,(let ((*foo* 42)) (declare (special *foo*)) *foo*)
<aeth>
Special/dynamic scope is useful when you don't want to pass in a variable or a bunch of variables just for something that's used 10+ calls deep in the call stack, e.g. streams used for input/output
<aeth>
Dynamic-extent is completely different, and is stack allocated rather than heap allocated, although it's only a request and can be ignored. (SBCL will either warn or give a note when it can't stack allocate when you request it. Perhaps other compilers as well.) https://www.lispworks.com/documentation/HyperSpec/Body/d_dynami.htm
<ixelp>
CLHS: Declaration DYNAMIC-EXTENT
<aeth>
smlckz: Dynamic-extent is basically working on reverse C/C++ rules, if you're familiar with those sorts of languages, where allocating on the heap is the exception not the norm (iirc, with malloc or new). Here, in CL, heap allocation is normal (unless it's small enough not to be heap allocated, such as fixnums and probably single-floats), but you can ask it to stack allocate if you know that it's e.g.
<aeth>
Sorry for the long short summary but the two things are completely different things.
istewart has quit [Quit: Konversation terminated!]
istewart has joined #commonlisp
<smlckz>
It seems to me that dynamic extent declares that the variables and functions are only used for so long that they could be stack allocated. It seems that stack allocation is an implementation detail, and some implementations can totally ignore it; but the idea is that the lifetime of the bindings is limited to their lexical scope (!). You can not have dynamically scoped variables to be declared
<smlckz>
to be in dynamic extent, can you? Have I understood this correctly?
shawnw has quit [Ping timeout: 258 seconds]
<aeth>
My impression is that it is basically saying "please stack allocate this" and the implementation can say "no" (or just ignore it) if it thinks you may be mistaken. Which, yes, seems to make it incompatible with dynamic-scope entirely, at least implicitly if not directly.
<aeth>
Although, to be fair, it's still the reverse of how C works because C can say "no" when you try to malloc (by returning a null pointer in that case).
<aeth>
Though CL has the added "can just ignore it" part.
<smlckz>
Please explain the last example given in the CLHS page on ''special'' declaration. I don't know what examples can be called contrived if this one can not be.
<aeth>
smlckz: that's why by convention we always use *foo* for such variables.
<smlckz>
Also, does the relation ''otherwise inaccessible part'' form a preorder over heap objects?
troojg has quit [Ping timeout: 260 seconds]
mzan has joined #commonlisp
<bike>
smlckz: the dynamic-extent declaration says that _the objects bound to the variables_ have dynamic extent. so for example, you can do (let ((x ...)) (declare (dynamic-extent x)) (let ((*x* x)) (foo))) where FOO reads *x* no problem. so it's not lexical scope.
<bike>
heh, that last special example is even described as contorted
<bike>
that example is unrelated to dynamic extent, of course. what it's trying to demonstrate is how special declarations affect variable references being special or lexical works.
<bike>
oh and you can declare special variables to have dynamic extent, no, so i probably could have made my dumb example simpler
<bike>
(let ((*x* ...)) (declare (dynamic-extent *x*)) (foo)). or just lexical (let ((x ...)) (declare (dynamic-extent x)) (foo x)) to demonstrate that the body of FOO can use the value even though it's not in the lexical scope of X.
<mrcom>
Dynamic scope isn't such a misnomer. It's saying that _a particular value binding_ has a limited extent. Sure, the variable's still there, but if you
<beach>
smlckz: You can think of the dynamic environment as a linked list of entries. One type of entry is a binding of a special variable. PROGV adds such an entry to the list and then executes the body using the new dynamic environment. SYMBOL-VALUE searches the dynamic environment for the first matching entry.
mrcom_ has quit [Quit: Leaving]
wacki has joined #commonlisp
shawnw has joined #commonlisp
X-Scale has quit [Quit: Client closed]
zxcvz has joined #commonlisp
jweeks` has quit [Read error: Connection reset by peer]
cercopith has joined #commonlisp
jweeks` has joined #commonlisp
cercopith_ has joined #commonlisp
cercopith has quit [Changing host]
cercopith has joined #commonlisp
cercopith_ has quit [Client Quit]
* beach
guesses that it didn't make sense.
rtypo has quit [Ping timeout: 264 seconds]
Pixel_Outlaw has quit [Quit: Leaving]
donleo has joined #commonlisp
pve has joined #commonlisp
contrapunctus has quit [Ping timeout: 252 seconds]
contrapunctus has joined #commonlisp
varjag has joined #commonlisp
mgl has joined #commonlisp
cage has joined #commonlisp
cage has quit [Excess Flood]
awlygj has joined #commonlisp
cage has joined #commonlisp
mgl has quit [Ping timeout: 255 seconds]
zxcvz has quit [Quit: zxcvz]
awlygj has quit [Quit: Lost terminal]
awlygj has joined #commonlisp
dstein64 has quit [Quit: ZNC 1.8.2+deb2build5 - https://znc.in]
dstein64 has joined #commonlisp
Opus has joined #commonlisp
grawlinson has quit [Quit: SIGTERM]
grawlinson has joined #commonlisp
danse-nr3 has joined #commonlisp
kamafam has joined #commonlisp
shka has joined #commonlisp
Guest71 has joined #commonlisp
shawnw has quit [Ping timeout: 272 seconds]
danse-nr3 has quit [Quit: on the move]
Cymew has joined #commonlisp
danse-nr3 has joined #commonlisp
Oddity has quit [Ping timeout: 276 seconds]
shawnw has joined #commonlisp
dans69504 has joined #commonlisp
danse-nr3 has quit [Ping timeout: 244 seconds]
kamafam has quit [Quit: kamafam]
amb007 has quit [Ping timeout: 260 seconds]
amb007 has joined #commonlisp
Oddity has joined #commonlisp
shawnw has quit [Ping timeout: 260 seconds]
dans69504 has quit [Remote host closed the connection]
danse-nr3 has joined #commonlisp
random-nick has joined #commonlisp
Oddity has quit [Ping timeout: 255 seconds]
mwnaylor has quit [Ping timeout: 272 seconds]
X-Scale has joined #commonlisp
uhuh has joined #commonlisp
amb007 has quit [Read error: Connection reset by peer]
amb007 has joined #commonlisp
decweb has joined #commonlisp
varjag has quit [Quit: ERC (IRC client for Emacs 27.1)]
semarie has quit [Quit: WeeChat 4.3.5]
danse-nr3 has quit [Quit: meal]
semarie has joined #commonlisp
X-Scale has quit [Ping timeout: 256 seconds]
euandreh1 has joined #commonlisp
phantomics has joined #commonlisp
edgar-rft_ has joined #commonlisp
edgar-rft has quit [Ping timeout: 252 seconds]
King_julian has joined #commonlisp
euandreh1 has quit [Remote host closed the connection]
varjag has joined #commonlisp
euandreh has joined #commonlisp
euandreh has quit [Remote host closed the connection]
prokhor has joined #commonlisp
rtypo has joined #commonlisp
X-Scale has joined #commonlisp
grawlinson has quit [Ping timeout: 272 seconds]
grawlinson has joined #commonlisp
X-Scale has quit [Ping timeout: 256 seconds]
Equill has joined #commonlisp
NotThatRPG has joined #commonlisp
<phantomics>
Hey, quick CLOS question
<phantomics>
Say I have a class feline with a %name property of '(:felinae), and I have a subclass of it called housecat with the %name property of '(:felinae :felis :catus)
<beach>
By "property", do you mean "slot"?
<phantomics>
These lists would be the :initforms of the %name slots - yes, slot
<beach>
Oh, I see.
<phantomics>
What is the best way to express that housecat's default %name should be the name of its parent class with '(:felis :catus) appended?
<phantomics>
Would this require the use of MOP, fetching the parent class's initform for the slot?
<bike>
my thought is that instead of having a %name slot, i'd have a %direct-names slot, which is (:felinae) for felines and (:felis :catus) for housecats. then, i'd have a NAMES method with append method combination that just grabs the slot value. i think that would work? maybe? might need multiple methods...
<phantomics>
Ok, so have a method to fetch them that calls the next method and appends, that makes sense
amb007 has quit [Ping timeout: 252 seconds]
uhuh has quit [Quit: ERC 5.5.0.29.1 (IRC client for GNU Emacs 29.1)]
amb007 has joined #commonlisp
<bike>
yeah, basically. i wouldn't mess around with mop unless you really have to, and i don't think you have to for this.
<phantomics>
I'll try that, thanks... also, is there a way to initialize an instance with an initarg that will be composed with the default initform in some way? I.e. I want to create a housecat instance with the %direct-name of '(:felis :catus :domesticus), and I want the initializer to just append the :domesticus to the default name list
<bike>
Not sure I understand. for one thing, is this not a class slot?
<phantomics>
Yeah, it's a class slot with a default value that can be appended to when initializing rather than outright replaced
<bike>
but if it's a class slot, you're not initializing it with the instance
<bike>
i mean :allocation :class here
<phantomics>
Ok, I'd be extending make-instance in that case
NotThatRPG has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<phantomics>
Is there a point in that method where I can get access to the initform for a slot, then do something with it and the initarg passed to make-instance?
King_julian has quit [Ping timeout: 260 seconds]
<bike>
but if it's a class slot, why would you want it to be changed by making an instance? that will change the slot for _all_ instances, not just the one being created
<phantomics>
I was thinking of changing it for just the created instance, if that's not how it works I'll look into another way
<bike>
if it's a class slot, the instance doesn't have its own slot. if you want instances with different names you don't want a class slot.
<bike>
anyway... if it's an instance slot, and you want an initarg to append, there's no built in way to do that, but you can make it work relatively simply with a shared-initialize method.
<bike>
have an :after method that takes some keyword argument (which is not the slot initarg). have it modify the slot by appending the value of that argument. bam.
<phantomics>
That makes sense, thanks. Take that keyword arg and use an :after method to append it
Guest71 has quit [Quit: Client closed]
sveit_ has quit [Ping timeout: 258 seconds]
istewart has quit [Quit: Konversation terminated!]
attila_lendvai has joined #commonlisp
X-Scale has joined #commonlisp
yitzi has joined #commonlisp
X-Scale has quit [Ping timeout: 256 seconds]
danse-nr3 has joined #commonlisp
Oddity has joined #commonlisp
JuanDaugherty has joined #commonlisp
dawids has joined #commonlisp
varjag has quit [Quit: ERC (IRC client for Emacs 27.1)]
NotThatRPG has joined #commonlisp
yitzi has quit [Remote host closed the connection]
Cymew has quit [Quit: Konversation terminated!]
JuanDaugherty has quit [Quit: JuanDaugherty]
eddof13 has joined #commonlisp
Catie` has joined #commonlisp
attila_lendvai has quit [Quit: Leaving]
danse-nr3 has quit [Quit: on the move]
Catie has quit [Ping timeout: 272 seconds]
attila_lendvai has joined #commonlisp
alcor has joined #commonlisp
danse-nr3 has joined #commonlisp
JuanDaugherty has joined #commonlisp
yitzi has joined #commonlisp
shawnw has joined #commonlisp
danse-nr3 has quit [Ping timeout: 248 seconds]
NotThatRPG has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<yitzi>
smlckz: The second returned value from READ-LINE is not an EOF indicator.
<yitzi>
It is a generalized boolean indicating whether there was a trailing newline.
<yitzi>
In your case, NIL in the first argument indicates EOF.
<smlckz>
hmm
<yitzi>
NIL in the first returned value...I should say
<yitzi>
You want it to be something other than NIL (which you could test with NULL) then you need to specificy via the error-value-p argument to READ-LINE.
Oddity has quit [Remote host closed the connection]
<yitzi>
If you want to avoid DO and POP in your join-by-spaces you can just do `(format nil "~{~a~^~%~}" lines)`
<yitzi>
It isn't any faster probably since FORMAT will expand to something roughly equivalent to what you are doing, but it is more terse and uses the iteration directive of FORMAT instead.
danse-nr3 has quit [Read error: Connection reset by peer]
attila_lendvai has quit [Ping timeout: 252 seconds]
danse-nr3 has joined #commonlisp
<smlckz>
You mean "~{~a~^ ~}", for ~% would make it join-by-lines
<yitzi>
"~(~a~^~%~}" is equivalent to join-by-lines.
eddof13 has joined #commonlisp
mrcom is now known as mrcom_
<mrcom_>
Just for you, Colleen, I changed my nick.
amb007 has quit [Read error: Connection reset by peer]
amb007 has joined #commonlisp
dawids has quit [Quit: Leaving]
NotThatRPG has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
danse-nr3 has quit [Ping timeout: 252 seconds]
amb007 has quit [Ping timeout: 255 seconds]
NotThatRPG has joined #commonlisp
eddof13 has joined #commonlisp
amb007 has joined #commonlisp
donleo has quit [Remote host closed the connection]
donleo has joined #commonlisp
awlygj has quit [Quit: leaving]
eddof13 has quit [Quit: eddof13]
<Shinmera>
Good news: we've gotten to the point where I get to debug my OS interop layers for the NX
<Shinmera>
Bad news: it takes four (4) minutes for me to see the results of any change I make to the code
ym has joined #commonlisp
<Shinmera>
Also there's no interactivity and many classes of error don't produce a backtrace at all
<Shinmera>
So debugging is heck
<Shinmera>
But it finally feels like the famed first triangle is somewhat in sight
waleee has joined #commonlisp
cage has quit [Remote host closed the connection]
cage has joined #commonlisp
cage has quit [Excess Flood]
cage has joined #commonlisp
cage has quit [Excess Flood]
cage has joined #commonlisp
<kingcons>
Shinmera: I will pray you need as few iterations to triangle as possible.
<Shinmera>
well, as few as possible is zero, but that's already past, so
<kingcons>
lol, fair enough. "as few remaining"
<Shinmera>
I'm expecting it to be a lot because not only am I not very smart, I'm also far too used to having the computer yell at me a couple thousand times before my semi-random keymashing produces the desired result
mgl has joined #commonlisp
<younder>
Funny, over here I am usually the one yelling at the computer..
<Shinmera>
it's a mutually abusive relationship
<Shinmera>
my psychologist tells me it isn't healthy, but alas I'm too far gone
john3 has quit [Quit: WeeChat 4.0.5]
cage has quit [Changing host]
cage has joined #commonlisp
eddof13 has joined #commonlisp
<skin>
If I submitted a paper to the European Lisp Symposium and it were accepted, could I give the talk remotely or would I need to fly in?
<skin>
Does anyone know?
<selpoke>
there have been remote talks before, including an entire symposium done remotely
<selpoke>
i am not involved in organising so i dont know the rules this time
<skin>
"talk to the organizers", that's fair. I'll get on that.
<skin>
Thanks
<selpoke>
no problem
_triffid has quit [Remote host closed the connection]
triffid has joined #commonlisp
<gilberth>
Does someone know where in the spec it is said that a parameter name may not occur twice in a lambda list? I can't find it. I want to know whether this applies to destructuring lambda lists as well.
<bike>
i remember being unable to find that too
<gilberth>
Oh!
<gilberth>
So we made this one up?
mwnaylor has joined #commonlisp
<gilberth>
I noticed that it is inconsistent. While a duplicate parameter name is caught with LAMBDA in most cases with most Lisps, it often is not with DESTRUCTURING-BIND. Sigh.
<Shinmera>
skin: You are heavily encouraged to attend in person if you submit. However, if you get accepted and cannot, you may submit a video recording of your talk instead.
<Shinmera>
We will not do live remote presentations anymore, though
<skin>
Thanks :) Helpful. If I get accepted, it'd be nice to come. It's just >$1200 so we'll see :)
<Shinmera>
If you can combine it with a europe trip it'd be very worth it!
<aeth>
destructuring-bind needs to be better specified, but at least it's better than LOOP destructuring which doesn't even error when the input doesn't match the pattern (which is probably what people want! random NILs being inserted are very hard to find the source of!)
<skin>
That is very interesting.
<Shinmera>
but yeah, we get it and don't want to exclude members for financial reasons
<aeth>
Hopefully implementations can agree on some de facto D-B standards
<Shinmera>
it's just also a significant dip in quality for in-person attendants and a significant increase in work for the team to have recorded talks
<Shinmera>
so we prefer to avoid it when possible
<skin>
Yeah, I hear that.
<skin>
Also, couldn't find any lisp-centric journals. Any input on that?
<Shinmera>
there are none
<skin>
ELS it is :)
<aeth>
If I ever did an ELS talk, prerecorded would probably be better than in person... graphics stuff. Less chance for something to go wrong live.
<Shinmera>
we'll be sure to publish more specific guides on what we expect for presenters
<ixelp>
Journal of Functional Programming | Cambridge Core
<Shinmera>
if you're interested in academic acclaim lisp is the wrong avenue anyway lmao
<skin>
Yeah, I might submit this as a pearl
<skin>
I'm not an academic, just thought what I found was cool enough to share :)
<skin>
Maybe I'll just blog it. I don't know.
<Shinmera>
then ELS is perfect.
<Shinmera>
why not both
<skin>
Yeah, feels like it
<Shinmera>
I often wrote blogs in prep for a more rigorous paper
<skin>
I'll submit, not a bad idea. Who knowS? It might happen.
<aeth>
ELS is the conference. For papers, if it's very CLOSy or stateful, not FP (just CS in general? or maybe there's an OO-specific journal, there probably is). Else, an FP open access journal. Imo.
<skin>
A cool idea, blog + paper.
<skin>
It's all FP, but the point of the excercise is to make FP easier in a "typeless" / dynamically typed setting. Trying to think of how to package that up for Haskellers is ... unappetizing
mgl has quit [Ping timeout: 258 seconds]
<skin>
It's still cool FP in its own right, though. I'll share here when I have something polished enough to share.
msv has quit [Remote host closed the connection]
<Shinmera>
just as lisp remains unappetising for non-lispers in general :)
<aeth>
skin: It's just that Lisp is (usually... since you can do anything in it) still typically FP, especially in contrast to most other languages. Even if FP research/literature is mostly type-system-oriented these days.
msv has joined #commonlisp
<skin>
Yeah, true. I'll think about it. First I have to write something up worth sharing.
<aeth>
I suppose the other thing that might not really fit FP (other than OOP) is numerical, where you're just SETFing a bunch of arrays. Though that depends on the interface you present because macros can hide a lot.
<Shinmera>
In general for ELS questions feel free to ping either me or SAL9000 on here at any time.
alethkit is now known as kitaleth
<gilberth>
bike: 3.4 says "A lambda list is a list that specifies a set of parameters [...]" So when we split hairs we can say being a set implies that there are no duplicates.
<gilberth>
Which makes sense as otherwise matching declarations with parameter variables becomes ambigious. However, what about LET and LET*?
mgl has joined #commonlisp
<Shinmera>
what about them
xlymian` has quit [Ping timeout: 276 seconds]
<bike>
i think that hair's pretty weak.
X-Scale has joined #commonlisp
wacki has quit [Ping timeout: 248 seconds]
<gilberth>
Like (LET* ((X A) (X B)) (DECLARE (FIXNUM X)) ...) does that declaration apply to both X? Only one? If so, which one?
Pixel_Outlaw has joined #commonlisp
<aeth>
I'd think it applies to all
<Shinmera>
the scope of the binding is nested, the declare applies to the innermost scope
wacki has joined #commonlisp
<Shinmera>
from clhs declare type: "The meaning of a type declaration is equivalent to changing each reference to a variable (var) within the scope of the declaration to (the typespec var)"
<Shinmera>
and from clhs let: "The special form let has the property that the scope of the name binding does not include any initial value form. For let*, a variable's scope also includes the remaining initial value forms for subsequent variable bindings."
<Shinmera>
seems pretty cut and dry to me
<gilberth>
Shinmera: What about SPECIAL. It doesn't help to look at type declarations. There could be all kind of declarations.
<Shinmera>
but it is almost 2300 and I shouldn't be speclawyering at this hour so I'll leave y'all to it
<gilberth>
And what if I make it parallel? (LET ((X A) (X B)) (DECLARE (FUNNY X)) ...)
<Shinmera>
what about it? the first X can't be visible anyway
<Shinmera>
so it doesn't matter
X-Scale has quit [Ping timeout: 256 seconds]
<gilberth>
It does matter. You said the inner applies. So (LET* ((X "fourty-two") (X 42)) (DECLARE (TYPE FIXNUM X)) ...) is ok. Is (LET ((X "fourty-two") (X 42)) (DECLARE (FIXNUM X)) ...) ok as well?
<gilberth>
What about ((LAMBDA (X X) (DECLARE (TYPE FIXNUM X))) "fourty-two" 42)? Lambda lists are bound sequentially in general.
<Shinmera>
The scope of X in LET does not include the bindings, only the body. Since the bindings are sequential however, the second binding overrides the first. Therefore the declare applies to the second since the first is effectively shadowed.
<Shinmera>
But again, I'll excuse myself.
<aeth>
If (let* ...) was equivalent to (let ... (let ... (let ...))) as far as the rules were concerned, then I would assume that the DECLARE would only work on the final variable no matter what. But apparently this isn't the case, and you can ,(let ((x 42)) (let ((y 43)) (declare (type integer x)) (values x y)))
<aeth>
But only applying to the final X doesn't seem like the obvious way to read a LET* with a DECLARE on X after a LET* with more than one X, because how would you even DECLARE the first X? You wouldn't be able to with LET* at all.
<gilberth>
aeth: It's not that trivial with LET*. While ,(let ((x 10)) (let ((y (symbol-value 'x))) (declare (special x)) y)) works, ,(let ((x 10)) (let ((y (symbol-value 'x))) (declare (special x)) y)) does not.