<spiaggia>
I grepped for it in the TeX files of the dpANS.
<makomo>
i've looked at those and it's clear to me what they do i think, but i was still hoping for a larger explanation
<makomo>
usually the stuff that's in the glossary is defined somewhere in the standard explictily
<spiaggia>
Oh, you want an explanation? I can give that to you.
scymtym has quit [Remote host closed the connection]
<makomo>
i think i understand the concepts because it's not so different from C++'s storage duration for example
<makomo>
it's the same concepts/issues regarding lifetime
HDurer has quit [Ping timeout: 260 seconds]
<spiaggia>
I shall have to take your word for it.
<makomo>
but i thought there would be a bigger formal definition for them
<White_Flame>
it's also the definition that necessitates thread-local
<makomo>
White_Flame: oh i remember that conversation from the other day but i wasn't following closely. where does it do that?
<White_Flame>
but yes, RAII-style scope boundaries are basically equivalent to dynamic extent
<White_Flame>
makomo: in the glossary definition of dynamic extent
<makomo>
that's what one would call "automatic storage duration" in C++
<White_Flame>
other threads are not "within the execution of a particular form"
<White_Flame>
indefinite extent means that the language mechanics don't make a reference undefined
<spiaggia>
makomo: There is no mention of thread-local in the standard, simply because there is no mention of threads in the standard.
<makomo>
spiaggia: yeah, true
<makomo>
White_Flame: yup. i think of it as just because something that has been malloc'd but never free'd :-)
<makomo>
s/because//
<White_Flame>
although the GC will eliminate non-referenced objects, which might fall in the same technical vocabulary
<makomo>
right, i was thinking of that
<White_Flame>
but it's still indefinite when that will happen
<White_Flame>
if at all ;)
<makomo>
yep
<makomo>
White_Flame: hm so, this implies thread-locality only if we assume the existence of threads and their usual behavior right?
<White_Flame>
"an extent whose duration is bounded by points of establishment and disestablishment within the execution of a particular form. "
<White_Flame>
depends on how you define "within" </bill clinton>
<White_Flame>
but thread locality is certainly compatible with that language
<makomo>
White_Flame: iirc, the whole discussion was started because of the question whether every thread has its own dynamic environment and whether they share the global dynamic environment?
<hajovonta>
hi
<makomo>
hello!
<makomo>
hajovonta: how did you presentation go? :-)
robotoad has quit [Quit: robotoad]
<makomo>
your*
<hajovonta>
makomo: I haven't hold it yet, first my colleague will do it on the topic of Prolog, this Wednesday as planned
<hajovonta>
I'll do it maybe next week
<makomo>
ah
<hajovonta>
and we will have one on Erlang
<makomo>
you should also sneak a prolog implementation in lisp into your talk :^)
<makomo>
"remember that language from the last time? well here's a 50 line implementation"
<makomo>
or something like that
<makomo>
:-D
<hajovonta>
but Erlang and Prolog are also being teached on our universities, so Lisp is the most alien of all of them
<makomo>
hm cool
<hajovonta>
makomo: I've heard there is a simple Prolog implementation, but I'm not sure if that is something useful or only a subset of some standardized Prolog because I'm not familiar with the language
<hajovonta>
makomo: also I don't have pointers (but Google will surely help me out with that :)
<makomo>
it's probably only just a subset. writing a serious prolog implementation would certainly take more than 50 lines.
<makomo>
but as a toy tongue-in-cheek example it's nice :D
trittweiler has joined #lisp
<hajovonta>
yes, that would be nice :)
karswell has quit [Remote host closed the connection]
<White_Flame>
makomo: the answer is yes to both.
karswell has joined #lisp
<White_Flame>
the thread environments could be considered overlays onto the shared global environment
<White_Flame>
and "environment" really only encapsulates the special variable bindings here
milanj has joined #lisp
<makomo>
and certainly stuff like handler bindings, etc.? i.e. the *dynamic* environment
<White_Flame>
ah, yes
shangul has joined #lisp
robotoad has joined #lisp
spiaggia has quit [Ping timeout: 248 seconds]
red-dot has quit [Quit: Going offline, see ya! (www.adiirc.com)]
jibanes has quit [Ping timeout: 240 seconds]
markoong has joined #lisp
markoong has quit [Client Quit]
markoong has joined #lisp
surya has joined #lisp
shka_ has quit [Ping timeout: 256 seconds]
attila_lendvai has joined #lisp
attila_lendvai has joined #lisp
varjag has joined #lisp
Kundry_Wag has joined #lisp
jibanes has joined #lisp
shangul has quit [Ping timeout: 248 seconds]
Folkol_ has joined #lisp
mlf|2 has quit [Read error: Connection reset by peer]
shangul has joined #lisp
m00natic has joined #lisp
smurfrobot has joined #lisp
Murii has joined #lisp
Cymew has joined #lisp
smurfrobot has quit [Ping timeout: 260 seconds]
shangul has quit [Ping timeout: 260 seconds]
HDurer has joined #lisp
HDurer has joined #lisp
HDurer has quit [Changing host]
shrdlu68 has quit [Ping timeout: 276 seconds]
_cosmonaut_ has joined #lisp
HDurer has quit [Ping timeout: 240 seconds]
dddddd has joined #lisp
HDurer has joined #lisp
scymtym has joined #lisp
<makomo>
does COMPILE interact in any way with EVAL-WHEN?
<makomo>
i've been reading that + other sections in 3.2 Compilation for the past hour :-)
<makomo>
also read fare's EVAL-WHEN post
<makomo>
but i still didn't catch all the details
<beach>
The use of the situation :execute (or eval) controls whether evaluation occurs for other eval-when forms; that is, those that are not top level forms, or those in code processed by eval or compile. If the :execute situation is specified in such a form, then the body forms are processed as an implicit progn; otherwise, the eval-when form returns nil.
<makomo>
LOADing a source file is the :execute situation
Kundry_Wag has quit [Ping timeout: 264 seconds]
<makomo>
ah, my question wasn't formulated very well. i meant to ask does it interact with :compile-toplevel and :load-toplevel
<makomo>
so the answer would be no?
<makomo>
but it does interact with :execute
robotoad has quit [Quit: robotoad]
<beach>
I think that's what it says, yes.
<makomo>
and the fact that EVAL might perform implicit compilation doesn't mean anything right, i.e. it still only fires with :execute?
hhdave has joined #lisp
<beach>
makomo: Yes, if EVAL does implicit compilation, it must still respect the restrictions of EVAL in the standard.
<makomo>
if the answer is yes, is that due to the fact that EVAL doesn't consider the stuff it's evaluating a top-level form, or because it's just special cased by the standard somewhere
<makomo>
ah
<beach>
makomo: In other words, COMPILE or EVAL can not pretend to be the file compiler.
<makomo>
so the latter, but i guess "special cased" isn't really a proper thing to say
<makomo>
it's just the way it's defined
<beach>
Yeah.
<makomo>
beach: i see, that's what i was looking for
<makomo>
thanks :-)
epony has joined #lisp
stardiviner has joined #lisp
<makomo>
so the notion of "top-level forms" only comes into play with the file compiler then?
wigust has joined #lisp
ZigPaw has quit [Read error: Connection reset by peer]
ZigPaw has joined #lisp
Tordek has quit [Ping timeout: 276 seconds]
<jackdaniel>
word "only" gives it too little credit, most software is compiled in the end file-by-file, not from the repl. but you are right, top-level forms are important when you compile files
vert2_ has quit [Ping timeout: 256 seconds]
<jackdaniel>
s/not from the repl/not form by form/
robotoad has joined #lisp
bend3r has quit [Ping timeout: 248 seconds]
svillemo1 has joined #lisp
<makomo>
jackdaniel: heh i guess. thanks :-)
<jackdaniel>
(for instance you expect, that your defun will be visible to other functions in your file)
shrdlu68 has joined #lisp
svillemot has quit [Disconnected by services]
svillemo1 is now known as svillemot
<makomo>
so there is not portable way to use the file compiler on stuff "from memory"?
sebastien_ has joined #lisp
<makomo>
(i get that it's called the *file* compiler, but still :-))
<makomo>
s/not/no/
heisig has joined #lisp
<MichaelRaskin>
(compile nil function-object) will return a compiled-function object.
<beach>
Why would you want to lie to your implementation?
<beach>
makomo: ↑
robotoad has quit [Client Quit]
MichaelRaskin has quit [Quit: MichaelRaskin]
<makomo>
beach: well i wouldn't, but currently i'm exploring the details of how the file compiler and eval-when work. i'm not sure if one would even want the effects of the file compiler for "in-memory" stuff, but i don't see why not
<beach>
If you do, you give the :EXECUTE situation.
<makomo>
i.e. why can't i take an arbitrary string and tell the file compiler to compile it, just like it would do after reading (in the "stream of text" sense) it
ZigPaw has quit [Quit: Vanishing into darkness in 1..2..3...]
robotoad has joined #lisp
stnutt has quit [Ping timeout: 260 seconds]
<makomo>
after reading the file*
ZigPaw has joined #lisp
stnutt has joined #lisp
<jackdaniel>
makomo: that'd require VFS which is not part of CL standard (and not implemented in any implementation so far afaik)
<jackdaniel>
you may create a macro, which takes your string, writes it to temporary file and compiles it with compile-file
<jackdaniel>
that is what slime's C-c C-c does fwiw
<makomo>
jackdaniel: that's one way to do it, but what about the standard defining something like COMPILE-STRING?
<jackdaniel>
it does not define such thing, period
<jackdaniel>
;)
<makomo>
well, exactly, which is my point :D
HDurer has quit [Ping timeout: 240 seconds]
<shrdlu68>
You could just create temporary files...
stardiviner has quit [Ping timeout: 245 seconds]
<jackdaniel>
makomo: I'd go with temporary files for now (there is no other way around that afaik). When vfs becomes *the thing* (probably never snh) then you will be able to create a virtual file from string
varjag has quit [Quit: ERC (IRC client for Emacs 24.5.1)]
HDurer has joined #lisp
HDurer has joined #lisp
HDurer has quit [Changing host]
rippa has joined #lisp
varjag has joined #lisp
<makomo>
shrdlu68: jackdaniel: mhm
shrdlu68 has quit [Remote host closed the connection]
shrdlu68 has joined #lisp
red-dot has joined #lisp
attila_lendvai has quit [Ping timeout: 265 seconds]
robotoad has quit [Quit: robotoad]
DemolitionMan has joined #lisp
Tordek has joined #lisp
skapata has joined #lisp
vert2 has joined #lisp
bend3r has joined #lisp
milanj has quit [Quit: This computer has gone to sleep]
attila_lendvai has joined #lisp
shrdlu68 has quit [Remote host closed the connection]
shrdlu68 has joined #lisp
milanj has joined #lisp
Folkol_ has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
Folkol_ has joined #lisp
shrdlu68 has quit [Ping timeout: 255 seconds]
shrdlu68 has joined #lisp
ZigPaw has quit [Quit: Vanishing into darkness in 1..2..3...]
python476 has joined #lisp
shrdlu68 has quit [Ping timeout: 240 seconds]
milanj_ has joined #lisp
shrdlu68 has joined #lisp
milanj has quit [Ping timeout: 268 seconds]
ZigPaw has joined #lisp
froggey has quit [Ping timeout: 276 seconds]
ZigPaw has quit [Quit: Vanishing into darkness in 1..2..3...]
python476 has left #lisp ["ERC (IRC client for Emacs 26.1)"]
ZigPaw has joined #lisp
EvW has joined #lisp
ZigPaw has quit [Client Quit]
ZigPaw has joined #lisp
pagnol has joined #lisp
doesthiswork has joined #lisp
fraya has joined #lisp
attila_lendvai has quit [Ping timeout: 264 seconds]
red-dot has quit [Quit: Going offline, see ya! (www.adiirc.com)]
jmercouris has joined #lisp
iAmDecim has quit [Ping timeout: 260 seconds]
wildbartty has joined #lisp
smurfrobot has joined #lisp
Folkol_ has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
Folkol_ has joined #lisp
_cosmonaut_ has joined #lisp
smurfrobot has quit [Ping timeout: 264 seconds]
Folkol_ has quit [Client Quit]
buster-blu has joined #lisp
buster-blu has left #lisp [#lisp]
Folkol_ has joined #lisp
shrdlu68 has quit [Ping timeout: 240 seconds]
shrdlu68 has joined #lisp
Bronsa has joined #lisp
Kundry_Wag has joined #lisp
shrdlu68 has quit [Ping timeout: 240 seconds]
Folkol_ has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
shrdlu68 has joined #lisp
Folkol_ has joined #lisp
EvW has quit [Ping timeout: 276 seconds]
lumm has joined #lisp
EvW has joined #lisp
Folkol_ has quit [Client Quit]
shrdlu68 has quit [Ping timeout: 260 seconds]
shrdlu68 has joined #lisp
SenasOzys has quit [Ping timeout: 264 seconds]
quazimodo has joined #lisp
AetherWind has quit [Quit: Leaving]
SaganMan has quit [Ping timeout: 260 seconds]
EvW has quit [Ping timeout: 245 seconds]
BitPuffin has joined #lisp
m00natic has quit [Remote host closed the connection]
Kundry_Wag has quit [Ping timeout: 240 seconds]
SaganMan has joined #lisp
fm4d_ has joined #lisp
<fm4d_>
Hi, could someone explain this behaviour to me? https://pastebin.com/3ypJB8Cn I thought I understand closures in lisps and this really confuses me.
<beach>
fm4d_: You are modifying constant data.
<beach>
That is not allowed by the standard.
<fm4d_>
Why the 'var' variable behaves as if it is a part of closures surrounding the function.
Folkol_ has joined #lisp
red-dot has joined #lisp
<beach>
Try replacing '(a b c d e) with (list 'a 'b 'c 'd 'e).
<fm4d_>
That works, but why?
<beach>
fm4d_: When you have constant data like that, the implementation is free to reuse the same constant each time you call the function, because, like I said, you are not allowed to modify it.
<beach>
I told you.
<beach>
You are not allowed to modify constant data the way you are.
Folkol_ has quit [Client Quit]
<beach>
fm4d_: The consequences are undefined if you modify constants.
<fm4d_>
Hm
<beach>
And you just observed one possible consequence.
<fm4d_>
Thanks
<beach>
Anytime.
orivej has quit [Ping timeout: 265 seconds]
<hajovonta>
is the (list 'a 'b 'c 'd 'e) evaluated every time when the closure is called?
<beach>
hajovonta: Yes.
<beach>
And, technically, it is not a "closure", since it does not close over any lexical variables.
<beach>
The function TEST in the example is defined in the global environment, also known as the null lexical environment.
<hajovonta>
I know I asked this before, but.. I'm a bit confused over this null lexical environment thing. It is like when calling (eval) and then inside the eval I have null environment and can't access things outside that.
<beach>
If you mean things like (let ((x 10)) (eval 'x)), then yes, you are right, eval does not take into account the lexical variable x.
<beach>
The reason for that is to allow compiler writers to optimize the code.
<beach>
If EVAL had to take into account the lexical environment, then you would have to keep X alive after the call to (f x).
<beach>
And you would have to keep environment information available at run time.
<beach>
As it is now, the compiler writer is free to assume that X is dead after (f x).
<beach>
Furthermore, the compiler writer is allowed to replace the entire thing with (progn (f 10) (eval (read))) so that there is no longer any X.
pjb has joined #lisp
<beach>
Again, if EVAL had to take lexical environments into account, then a host of optimizations would not be possible, and then you (perhaps not you personally, but many people here) would complain that Common Lisp is slow because it is impossible to optimize the code.
gigetoo has quit [Ping timeout: 256 seconds]
<beach>
hajovonta: The creators of Common Lisp were very smart that way. They pushed the envelope of the language as much as they could, but without making it hard for the compiler writer to optimize.
<hajovonta>
beach: compiler optimization is a good thing, but I have a (I think) special case when I would need to generate and evaluate forms at runtime, with access to the lexical environment. And I don't know yet how to do that.
<hajovonta>
Common Lisp is very flexible so I think I will find a way eventually.
<beach>
You might be able to use some implementation-specific solution.
<hajovonta>
I use SBCL. Does it have one?
<beach>
After all, SBCL with SLIME is able to evaluate forms relative to a lexical environment.
<beach>
You are still not protected from the compiler removing variables that are not lexically apparent.
hjek has joined #lisp
hjek has left #lisp [#lisp]
<hajovonta>
when I write (loop (eval (read-line))) I'm in null environment with every line?
<TMA>
another option would be to allow the capture of the lexical environment -- this could be used to provide the information to eval as well as to let the compiler know optimizations are not permissible in this particular part of the code; to make that portably is not well specified in the standard (there are macros with &env for capturing the environment, but the standard eval does not accept it)
<beach>
"Evaluates form in the current dynamic environment and the null lexical environment."
<beach>
TMA: &environment arguments are about lexical environments at compile time.
<beach>
Not at run time.
siraben has joined #lisp
SaganMan has quit [Ping timeout: 260 seconds]
gigetoo has joined #lisp
Kundry_Wag has joined #lisp
quazimodo has quit [Ping timeout: 245 seconds]
quazimodo has joined #lisp
xificurC has joined #lisp
Cymew has quit [Read error: Connection reset by peer]
Cymew has joined #lisp
lukego has joined #lisp
<lukego>
recommend a reasonably portable/stable/efficient library for doing asynchronous sockets/timers ("state machine style")? cl-async? iolib?
Kundry_Wag has quit [Remote host closed the connection]
SaganMan has joined #lisp
pagnol has quit [Ping timeout: 260 seconds]
shrdlu68 has quit [Ping timeout: 260 seconds]
shrdlu68 has joined #lisp
smurfrobot has joined #lisp
shrdlu68 has quit [Ping timeout: 256 seconds]
shrdlu68 has joined #lisp
shrdlu68 has quit [Ping timeout: 248 seconds]
shrdlu68 has joined #lisp
smurfrobot has quit [Remote host closed the connection]
scymtym_ has joined #lisp
quazimodo has quit [Ping timeout: 264 seconds]
TCZ has joined #lisp
scymtym has quit [Ping timeout: 240 seconds]
hjek has joined #lisp
smurfrobot has joined #lisp
Folkol_ has joined #lisp
Kundry_Wag has joined #lisp
red-dot has quit [Quit: Going offline, see ya! (www.adiirc.com)]
pierpal has quit [Ping timeout: 260 seconds]
<makomo>
hajovonta: a thing that you could do is inject a let into the code that is being EVAL'd
<makomo>
so instead of (eval some-code) you would have (eval `(let (... bindings ...) ,@some-code))) :-D
<makomo>
the same thing applies to COMPILE
Folkol_ has quit [Ping timeout: 256 seconds]
<hajovonta>
the problem is essentially (let ((x 1)) (eval (read-from-string "(setf x 2)")) x)
<hajovonta>
bacuse inside eval, x is undefined
<makomo>
right, so you could embed this let into the code that eval is executing
<makomo>
(eval `(let ((x 1)) ,@(read-from-string "(setf x 2)")))
<makomo>
erm, perhaps without the @
<hajovonta>
right
<makomo>
but yeah, that x is then not visible to the environment that called EVAL in the first place
<makomo>
unless you use dynamic variables
<hajovonta>
yes, and the next time you call eval, you lose the injected values
Bronsa has quit [Remote host closed the connection]
<hajovonta>
but, as you say, it works: (defparameter x 1) (eval (read-from-string "(setf x 2)"))
Bronsa has joined #lisp
<makomo>
yup :/
<makomo>
the thing i'll get back to in a few weeks uses something like that
<makomo>
but modifies an object's slots instead of dynamic variables
red-dot has joined #lisp
<makomo>
since i need to load code at runtime, i don't see another way
<makomo>
actually, it modifies one of the slots, and that slot is hash table that stores variables of the object language (the one i'm implementing)
<makomo>
so that effect is persistent because that hash table is floating somewhere in the lisp image
<makomo>
just like with dynamic variables
quazimodo has joined #lisp
froggey has joined #lisp
<makomo>
and the reason i want that in the first place is so that the code of the object language can just say "a" to acess the variable "a" of a component within the object language
<makomo>
rather than having to say something like "(gethash 'a (variables *current-object*))" or something
<makomo>
i.e. so it doesn't have to use any implementation details of the object language implementation
<makomo>
so i inject LETs like "(let ((a ...thing with *current-object*...)) ...actual code...)"
<makomo>
now that i think about it, this is for reading the variables only. for setting the variables i should probably use something like a symbol-macrolet
<makomo>
but then it's injecting symbol-macrolets, so either way you're injecting something
<makomo>
i don't know whether there's a "better" way or if we should even be bothered by this way
orivej has joined #lisp
hjek has quit [Ping timeout: 276 seconds]
Kundry_Wag has quit [Ping timeout: 256 seconds]
smurfrobot has quit [Remote host closed the connection]
<xificurC>
I just got a question from colleagues what does "prog" stand for in progn or prog1, anyone knows?
Kevslinger has joined #lisp
<makomo>
"program"? :D
libre-man has quit [Quit: WeeChat 2.1]
<xificurC>
that's their guess but it doesn't make its usage much clearer
libre-man has joined #lisp
_cosmonaut_ has quit [Ping timeout: 256 seconds]
<makomo>
perhaps the sequence of forms that you give to prog can be thought of as a "program", i.e. a sequence steps to execute in that particular order
smurfrobot has joined #lisp
lukego has quit [Ping timeout: 260 seconds]
gigetoo has quit [Ping timeout: 240 seconds]
<xificurC>
which is no different to normal code :) And program usually refers to something bigger, this is just a random block of code grouped together
libre-man has quit [Client Quit]
libre-man has joined #lisp
* makomo
shrugs
<xificurC>
makomo: I'm not saying you're not right
<Xach_>
at ilc guy steele and someone else made a few jokes about the announcement of PROG back in the day. apparently it was pitched as making it possible to write programs in lisp.
<Xach_>
i'm not sure what historical announcement they referenced.
<makomo>
it was a guess anyway :-)
Bike has joined #lisp
gigetoo has joined #lisp
<Xach_>
lots of interesting results from googling: "the prog feature" lisp
hjek has joined #lisp
<nowhere_man>
Has anyone written a macro that contains a defmacro? I'm really struggling here.
hajovonta has quit [Ping timeout: 260 seconds]
_cosmonaut_ has joined #lisp
<xificurC>
`,`,`,`,@
<makomo>
lol
<makomo>
nowhere_man: what's the problem?
<nowhere_man>
Writing the "first-level" macro is very easy: (defmacro {lazy} ((&rest args) &body body) `(make-instance 'lazy-function :fun (lambda ,args ,@body)))
<shka>
nowhere_man: nested quotations are hard to understand
<nowhere_man>
Now I'd like to write several identical macros with the name and class changing
<nowhere_man>
shka: they are straight up mysterious, I've been playing with them for some time now
<makomo>
figuring out how nested backquote works is quite rewarding though
<pjb>
no, it's not evaluating (+ 1 2), since it occurs as is, in the result of `.
varjag has quit [Quit: ERC (IRC client for Emacs 24.5.1)]
Kundry_Wag has joined #lisp
<pjb>
You need eval, or a macro to evaluate the form: (eval (let ((l '((+ 1 2) (- 1 2) (* 3 4)))) ``(list ,,@l)) ) #| --> (list 3 -1 12) |#
red-dot has quit [Quit: Going offline, see ya! (www.adiirc.com)]
<pjb>
and since we have two ``, we need two evals or two macros: (eval (eval (let ((l '((+ 1 2) (- 1 2) (* 3 4)))) ``(list ,,@l)) )) #| --> (3 -1 12) |#
<pjb>
to get the final result.
Inline has joined #lisp
<jmercouris>
I'm trying to remember the word that is used to mark the end of a list
<jmercouris>
for example, if we have a circular singly linked list
<jmercouris>
there is an element you can use to know when you are going to loop over again
<jmercouris>
what is that element called?
<jmercouris>
sentinel
<jmercouris>
there we go
scymtym_ has quit [Ping timeout: 265 seconds]
<makomo>
pjb: isn't what i said true? your list is ((+ 1 2) (- 1 2) ...), and the result of evaluating the doubly nested backquote form twice is '(list 3 -1 12)
<makomo>
the elements have been spliced in *and* evaluated
<beach>
jmercouris: The word is more commonly used to mean a dummy element that is part of the representation of a data structure, but that is not seen by the interface to that data structure.
<beach>
jmercouris: The purpose being to simplify the algorithms on that data structure.
<beach>
jmercouris: For instance, if you represent an empty queue by a single CONS cell, then you remove the special case to test whether the head and the tail pointers are both NIL.
nika_ has joined #lisp
<jmercouris>
I'm thinking about what the last thing you said, why would we test to see if the head and tail is both NIL? to test for empty queue?
<pjb>
makomo: the evaluation is not done by the comma!
<beach>
jmercouris: Yes.
<jmercouris>
Aha, so in this case, the single cons cell is what we define the sentinel to be
<beach>
Exactly.
<jmercouris>
so we can just check if the cons cell is pointing to nil instead of performing two checks
<beach>
It will not be "seen" by the external interface.
<pjb>
makomo: (let ((e '(+ 1 2))) `(list ,e)) #| --> (list (+ 1 2)) |# you see that the comma evaluates E, but doesn't evaluate the result of E.
<jmercouris>
ok I see, seems I have been using this word incorrectly for a long time
<beach>
jmercouris: You typically check whether the head and the tail point to the same thing in order to determine whether the queue is empty.
<makomo>
pjb: right, because it is a single comma
<pjb>
And if you double the quotes and comma, even less: (let ((e '(+ 1 2))) ``(list ,,e)) #| --> (list* 'list (list (+ 1 2))) |#
<jmercouris>
beach: Yes, I remember now, thanks for the clarification
<beach>
jmercouris: Anytime.
<pjb>
makomo: again, you need something to evaluate the result of the backquote. Such as a compiler calling a macro and generating the code to evaluate the result of the macro, or an explicit call to eval.
<makomo>
pjb: is the thing on the right supposed to represent a "raw list" or the equivalent form that when evaluated gives the same thing?
<makomo>
on the right of your #| -->
<pjb>
makomo: don't confuse who does what. It's eval, or compile that will set things to evaluate the subexpression (+ 1 2).
<pjb>
makomo: it's the result.
<makomo>
so where does the "list*" symbol come from?
Cymew has quit [Remote host closed the connection]
<pjb>
--> means "evaluates to" or "the evaluation therefof results in"
<makomo>
oh, this is a single evaluation
<pjb>
makomo: it's the implementation dependent expansion of the #\` reader macro
<makomo>
yes, but i meant evaluating it twice
Cymew has joined #lisp
<pjb>
makomo: ` doesn't evaluate, it reads.
<makomo>
evaluating the doubly backquoted form *twice*
<makomo>
i know, yes
<makomo>
but if you evaluate the thing twice, you'll get what i said
<makomo>
maybe i wasn't very clear on how many times i was thinking of evaluating it
<pjb>
Yes. But it's the evaluating that evaluates, not the backquote or comma.
<makomo>
yes, of course
<makomo>
i never had an issue with that :-)
<makomo>
the thing that's not clear to me, is how to get to that behavior, using the formal rules of backquote described in the spec
<makomo>
so evaluating a doubly nested backquote form with ,,@a in it first splices in the elements of a, and then evaluates all of those elements
<makomo>
the first evaluation splices, the second evaluates the elements
<makomo>
splices the result of evaluation a, more precisely
<makomo>
evaluating*
Cymew has quit [Ping timeout: 256 seconds]
flamebeard has quit []
Folkol_ has joined #lisp
mindCrime has joined #lisp
EvW has joined #lisp
pierpal has quit [Quit: Poof]
pierpal has joined #lisp
Kundry_Wag has quit [Ping timeout: 248 seconds]
shrdlu68 has quit [Ping timeout: 240 seconds]
<pjb>
makomo: in reality both commas "expand" or substitute the result of expression following the comma. The only question is where the binding are sought. And this is where the parenthetical aspect of backquote and comma matters.
<makomo>
the question where the bindings are sought is a simpler problem to me and is easy to understand by analogy either with parentheses as you say, or with "ladders" (the so-called ladder algorithm or whatever it was)
<makomo>
the confusing thing for me is what does the left "," do with the expansion of ",@" in ",,@"
<pjb>
makomo: it traverses the first ` it finds on the left.
gigetoo has quit [Ping timeout: 245 seconds]
<pjb>
Notice in (let ((e '(+ 1 2)) (v (gensym))) `(let ((,v ,e)) `(list ,',v ,,v ,',e ,,e))) how we HAVE to use TWO commas to get the V and the E bindings that are in the outer LET.
<pjb>
On the other hand, a single comma is needed in the `(let ((,v ,e)), because there's only one ` to traverse.
<makomo>
that is completely clear to me and that is again the problem of evaluation
gigetoo has joined #lisp
<makomo>
evaluating the doubly backquoted form above twice would yield an error right?
<makomo>
because the gensym isn't bound to anything
FreeBirdLjj has joined #lisp
robotoad has joined #lisp
<makomo>
i.e. ,,v would fail after the second evaluation
<makomo>
and this is the formal spec for backquote
Folkol_ has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<pjb>
makomo: more interesting a question, is why the lambda body uses ``(,,g ,,(cdr n)) instead of (list g (cdr n))
pagnol has joined #lisp
<makomo>
using these formal rules i want to get at the observed behavior of ,,@
karlosz has joined #lisp
smurfrobot has joined #lisp
<pjb>
makomo: AFAICS, there's no difference between ``(,,g ,,(cdr n)) and (list g (cdr n)). It's the programmer loving ` and ,…
<makomo>
hmm
siraben has quit [Quit: ERC (IRC client for Emacs 26.1)]
<makomo>
isn't it there to doubly evaluate the g and the car?
scymtym has joined #lisp
<makomo>
the result of mapcar is a list of the form '(`(,a1 ,b1) `(,a2, b2) ...) where ai and bi are the results of evaluating g and (cdr n) in the i-th iteration of mapcar
<makomo>
well, without the QUOTE at the beginning
<makomo>
the elements of this list are spliced in front of a commad, meaning that all of these elements will be evaluated in the second evaluation
<makomo>
comma*
slyrus1 has joined #lisp
smurfrobot has quit [Ping timeout: 260 seconds]
<pjb>
makomo: to see what a reader macro reads something as, you can just type the form at the REPL, prefixed by quote, so that it's not evaluated, but just read.
<makomo>
that doesn't work for me because it pretty prints it
<makomo>
i'm not sure if that's sbcl's or slime's behavior, but i guess it is sbcl's
<pjb>
in ccl, '``(,,g ,,(cdr n)) --> (list* 'list* (list* g (list (list* 'list (list (cdr n))))))
<makomo>
i never look at how to disable the pretty printing
<makomo>
but all i would get are implementation details of sbcl anyway
<makomo>
i want to stay agnostic to the underlying representation
<pjb>
(setf *print-pretty* nil) ; but the printer for ` may do its work even without *print-pretty*.
<makomo>
looked*
<makomo>
let's see
<makomo>
nope, still the same output
<pjb>
yes, so ``,,g is needed, because g contains an expression that when evaluated will return a variable name…
<makomo>
yep
<makomo>
once-only is quite spooky :-)
asarch has quit [Quit: Leaving]
<pjb>
indeed.
<makomo>
but still, the main problem for me is the ,,@
<makomo>
these multiple tiers of evaluation are mostly ok
<pjb>
Well, you can say that it evaluate the following expression in the lexical context outside the second ` on the left.
MichaelRaskin has joined #lisp
<makomo>
right
karlosz has quit [Quit: karlosz]
Kundry_Wag has joined #lisp
<makomo>
the inner backquote will be evaluated in the lexical context set up by the outer let
karlosz has joined #lisp
<makomo>
well, set up by the let of the outer backquote*
FreeBirdLjj has quit [Remote host closed the connection]
cgay has quit [Quit: leaving]
cgay has joined #lisp
FreeBirdLjj has joined #lisp
cgay_ has joined #lisp
_cosmonaut_ has quit [Ping timeout: 256 seconds]
cgay has quit [Ping timeout: 245 seconds]
<beach>
Let's say I am using an ideal debugger, and I am stopped at the beginning of the form (f (g a) (h b)). Can we agree that if I execute a STEP OVER, command, then (g a) will be evaluated, then (h b), then the call to f will be made and I will find myself stopped at the end of the initial form?
FreeBirdLjj has quit [Ping timeout: 255 seconds]
<beach>
Now, if I am again stopped at the beginning of the form (f (g a) (h b)) and I execute the STEP IN command, can we then agree that I will probably find myself stopped at the beginning of the form (g a)?
gigetoo has quit [Ping timeout: 264 seconds]
varjag has joined #lisp
azimut has quit [Ping timeout: 265 seconds]
<beach>
My question is: Suppose I want the next stopping point to be the beginning of the first form of the function F, where would the current stopping point have to be located, and what is the name of the command that I need to execute?
azimut has joined #lisp
Myk267 has joined #lisp
<beach>
One possible answer would be: From the initial situation, I would issue a STEP IN command, followed by two step-over, which would take me to the end of the form (h b). I would then execute another STEP IN. Since there is no form to step into after (h b), I will instead step into the function F.
<beach>
Another one would be: From the initial situation, I would issue a STEP IN command, followed by two step-over, which would take me to the end of the form (h b). I would then execute a command that has yet to be defined, say STEP CALL, in order to step into the function F, whereas executing a STEP IN in that situation would step into the form following (f (g a) (h b)).
<beach>
I am sure there are more possibilities.
joast has quit [Quit: Leaving.]
MichaelRaskin has quit [Ping timeout: 256 seconds]
hhdave has quit [Read error: Connection reset by peer]
Kundry_Wag has joined #lisp
svillemot has quit [Ping timeout: 268 seconds]
hhdave has joined #lisp
cgay_ has quit [Ping timeout: 268 seconds]
cgay has joined #lisp
_cosmonaut_ has quit [Ping timeout: 264 seconds]
hhdave_ has quit [Ping timeout: 276 seconds]
jeosol has quit [Ping timeout: 260 seconds]
gigetoo has quit [Ping timeout: 264 seconds]
Myk267 has joined #lisp
kmurphy4 has joined #lisp
gigetoo has joined #lisp
<pjb>
beach: about no form after (h b) I would note that I would often like to see the result of the stepped over form before continuing (or possibly retry the stepped over form, stepping in this time). Therefore I would insert automatically a stopping point just before the call to the function F.
<pjb>
(but of course, only if there are arguments).
smurfrobot has joined #lisp
<beach>
Oh, yes, definitely.
<beach>
Either way, there will be a stopping point after (h b).
<pjb>
similarly when you're stepping inside a function, we want a stop point once the result is elaborated and we're ready to return, but before we unwind the scopes of the function, so that we may jump back inside the function to retry something.
<beach>
Absolutely.
<pjb>
Yes, after evaluating each argument. The thing is that stopping points can be fusionned if there are no evaluations between them.
<pjb>
We stop before and after arguments, before and after the call, before and after the return, etc. A lot of stopping will be merged.
<beach>
Yes, I have come to that conclusion too.
<pjb>
Perhaps things would be more obvious looking at the binding scopes, when they're established and unwound.
<beach>
Maybe so. I'll give it some more thought.
<beach>
Thanks for the input.
<beach>
[dinner is imminent]
<pjb>
Bon appetit!
<beach>
Merci!
hhdave has quit [Ping timeout: 256 seconds]
bbobb has joined #lisp
trittweiler has joined #lisp
fkac has joined #lisp
svillemot has joined #lisp
fkac has quit [Remote host closed the connection]
nckx has quit [Quit: Updating my GNU GuixSD server — gnu.org/s/guix]
nckx has joined #lisp
red-dot has joined #lisp
fkac has joined #lisp
SaganMan has quit [Quit: WeeChat 1.6]
jibanes has quit [Ping timeout: 256 seconds]
<cgay>
So, a different kind of input.
jibanes has joined #lisp
karswell has quit [Read error: Connection reset by peer]
gigetoo has quit [Ping timeout: 276 seconds]
smurfrobot has quit [Remote host closed the connection]
karswell has joined #lisp
shka_ has joined #lisp
smurfrobot has joined #lisp
EvW1 has joined #lisp
Bronsa has quit [Ping timeout: 264 seconds]
gigetoo has joined #lisp
Naergon has quit [Ping timeout: 245 seconds]
iAmDecim has quit [Ping timeout: 248 seconds]
smurfrobot has quit [Ping timeout: 240 seconds]
itruslove has quit [Remote host closed the connection]
Guest75834 has quit [Remote host closed the connection]
mflem has joined #lisp
<makomo>
how can i create a macro with the name being the value of a symbol
<makomo>
this might be bad style, but i'm interested how it could be done
<sjl>
the symbol being evaluated at macro expansion time?
<sjl>
macroexpansion of the defmacro
puchacz has joined #lisp
Kundry_Wag has quit [Remote host closed the connection]
Kundry_Wag has joined #lisp
<makomo>
i guess, yes
<makomo>
or maybe not
<puchacz>
hi, I have a web application in Lisp (hunchentoot etc.). I would like to add a backend server in Java, that would not be accessible in the external world, but my Lisp web application would talk to it. What shall I use please? jfli, lisplets, foil, abcl maybe....?
<puchacz>
I don't want the JNI mess, just socket/text communication
<makomo>
sjl: when the defmacro is expanded, i want it to expand into something that will define a macro with the name being the current value of the symbol i gave it
<sjl>
makomo: can you give an example of the usage you're hoping to get?
<sjl>
(defmacro define-macro-named (symbol &body body) `(defmacro ,(symbol-value symbol) ,@body)) would work if you don't care about lexical bindings
<makomo>
the inner defmacro will always be named MACRO-NAME currently
<makomo>
sjl: and if i wanted the name to be the result of an expression?
gigetoo has quit [Ping timeout: 260 seconds]
<makomo>
sjl: for example, (define-macro-named (concatenate 'string "HI" "-THERE") ...)
fkac has quit [Ping timeout: 256 seconds]
<pjb>
makomo: your define-macro-named can evaluate the parameter or not, as it wants.
iAmDecim has joined #lisp
svillemot has quit [Ping timeout: 268 seconds]
<makomo>
hmm
<pjb>
You can have another intermediate macro. But the thing is that the name of the ultimate macro will have to be known at compilation time anyways, so it has to be evaluated in the macro-expansion environment (or in the compilation environment).
svillemot has joined #lisp
<pjb>
makomo: the point is to know who provides the expression. In general, it's the macro defining macro that computes the names…
<makomo>
define-maker is fine, and takes a symbol that names the class
<makomo>
but now i want to create generate-maker that takes an expression that evaluates to the name of the class
<makomo>
and then create a macro with the corresponding name
<makomo>
how can i evaluate the expression bound to "name" without having to call EVAL or the like
<makomo>
i don't see a way
<Bike>
you expand into something that evaluates.
karswell_ has joined #lisp
<makomo>
hm, let's see
<makomo>
but it's the same problem again, only within the expansion
<Bike>
for example you'd have (generate-maker (class-of (make-instance 'some-class))) expand into (defmacro whatever (args &body body) (make-instance (class-of (make-instance 'some-class)) :fun (lambda ,args ,@body)))
iAmDecim has quit [Ping timeout: 276 seconds]
nika_ has quit [Quit: Leaving...]
<Bike>
sorry, `(make-instance ...)
<makomo>
yes, but i want to determine this "whatever" by evaluating the expression
orivej has joined #lisp
<Bike>
Oh. Well then yes you'd need to evaluate.
<Bike>
At least for using defmacro.
karswell has quit [Ping timeout: 256 seconds]
<makomo>
right, for defun i could use symbol-function and setf right?
<Bike>
You could alternately expand into (setf (macro-function whatever) ...)
<makomo>
ahhh
<makomo>
macros have that too
<makomo>
hmm
<makomo>
and i would have to evaluate using EVAL right?
<makomo>
so if macro-function didn't exist, i.e. if there was no way to define a macro other than defmacro (i know it doesn't make much sense do provide such an api, but let's speak hypothetically)
<makomo>
then there would be no other way other than using EVAL within the body of the macro (not the expansion)?
ckonstanski has quit [Remote host closed the connection]
<TMA>
makomo: well, as defmacro is a macro itself it expands to something that does its shenanigans. that something would be necessarily implementation defined though
<makomo>
true. so there will always be a non-macro way to do it, the only issue being whether it is an implementation detail of the api or not
<makomo>
(setf (macro-function ...) ...) is portable though, right?
<TMA>
in the end you need a special form or a function to do anything.
<makomo>
so if for example CL didn't provide macro-function and the ability to set the macro function, you'd have no portable way of defining macros at run-time, right?
<beach>
Simpler question about debugger interface: suppose you have a sequence of forms to evaluate, like the body of a PROGN or the argument forms of a function call. Would you prefer to go from the beginning of one expression to the beginning of the next one, or from the end of one expression to the end of the next one?
<beach>
I am asking because as far as the program counter is concerned, the end of one expression is probably the same address as the beginning of the next. My question is more where you would like to see the cursor each time.
<pjb>
makomo: if you know that macro functions are functions taking two arguments: a form, and an environment, then yes.
<makomo>
pjb: the point is just toying around :-)
Jesin has joined #lisp
smurfrobot has quit [Remote host closed the connection]
<beach>
My question concerns the STEP OVER command, of course.
<pjb>
beach: well, you need to stop at the beginning, but then it's better to stop at the end of each form to report the results of each form.
<makomo>
pjb: good point about princ, but i intentionally didn't care about that
<pjb>
ok
<beach>
pjb: OK, so you would prefer to go from end to end?
<pjb>
beach: of course, the PC is the same: we just stop between two forms.
comborico1611 has joined #lisp
<beach>
pjb: It's not that easy. They could be physically separated in the source.
<makomo>
pjb: i still don't see how your code solves anything though. you're not calling define-maker anywhere
<beach>
pjb: Hence my question.
<pjb>
"previous form (foo) returned values a;b;c . form (bar) will evaluate next"
<pjb>
or "entering progn. form (foo) will evaluate next"
<beach>
pjb: Er, I am talking about a GUI here.
sjl has quit [Quit: WeeChat 2.2-dev]
<beach>
Which parenthesis would you like to have a red background?
<TMA>
beach: I expect to have the cursor at the beginning of the form about to be evaluated.
<beach>
pjb: The closing one or the opening one?
<pjb>
beach: in a gui, you can display things in different places, you can insert lines, etc.
<beach>
TMA: Thanks.
<pjb>
beach: it's customary to have an indicator (and for breakpoints too) at the beginning of the line.
<beach>
pjb: Yes, and I don't always want that.
<pjb>
So I think the best would be to insert space between the two form to display the indicator or display things.
<makomo>
Bike: so is it true that to achieve what i want i would either have to use EVAL within the macro's body or expand into something like (setf (macro-function ...) ...) as you said?
<beach>
pjb: Of course there is a space between the forms.
<pjb>
Eg. could use a phylactery containing the results of the previous form, and pointing between the two forms.
<Bike>
defmacro doesn't evaluate, so probably yeah.
<pjb>
It would work as well if the two forms are on the same line (eg. arguments) or on different lines (progn).
sjl has joined #lisp
<beach>
pjb: But what if one is the condition of an IF and the other is far away (the ELSE branch)?
<pjb>
perhaps with two arrows in this case?
<TMA>
beach: that being said, the form about to be evaluated is ill-specified itself -- is it the innermost form to be evaluated? or the outermost? [say the "next" form is (cons (cdr x) (car x)) ... I don't know in what case I would expect the cursor be: _(cons (cdr x) (car x)) and in which cases (cons (cdr _x) (car x)) ]
<pjb>
Furthermore, the user could want to keep around some phylactery, "pinning" them so the arrows would have to be elastic to let the user move the phylactery around to read what's below.
<pjb>
beach: perhaps you could have a look at Racket. IIRC they have a debugger that does something like this.
<pjb>
Notably to show the backtrace.
<beach>
OK, thanks to both of you. I'll go back to my couch and think.
<beach>
TMA: I was talking about the STEP OVER command, which does not enter into sub-forms. In your example, the next form would be the one following (cons (cdr x) (car x)).
<beach>
Anyway, more thinking to do...
<pjb>
On one hand, inserting stuff may be bothering. On the other, displaying windows above the source too. In any case, if it's automatic, it's better than if it requires manual manipulation…
<pjb>
For good UI design, we have to experiment.
smurfrobot has joined #lisp
<TMA>
beach: ok. in step over mode it is definitely the opening parenthesis ... but what is a step over mode? isn't the step-over step-into decision postponed until after some feedback is given to the user?
<beach>
pjb: I don't consider inserting stuff in the kind of window I am talking about. The user would have to specify "edit" at which point some editor would be executed with the file in question.
<pjb>
beach: some debuggers also have a "finish" command, to continue execution until the end of the current function.
<beach>
TMA: The decision is made by the user in the form of different commands.
sauvin has quit [Read error: Connection reset by peer]
<pjb>
In case of lisp, it could be the end of the current form.
<beach>
pjb: Yes, that's STEP OUT. I am not asking about that right now.
<pjb>
So: step over, step in, step into, and finish.
<beach>
pjb: I guess so, yes.
nickenchuggets has joined #lisp
nickenchuggets has joined #lisp
nickenchuggets has quit [Changing host]
<beach>
Maybe step in and step into are the same.
<pjb>
step in would stop before arguments, step into would stop at the entry of the function.
<beach>
Maybe finish and step out are the same.
<pjb>
But you're right better names should be found.
<pjb>
it's confusing.
<beach>
pjb: Sure, yes, I see.
<TMA>
beach: yes, but in the 'usual' debuggers the selection is only done after the cursor is shown, so you cannot decide where to put it based on the choice the user has not yet made
<beach>
TMA: Correct.
<MichaelRaskin>
Hm, yes, a diifference between going through every subform in the source of the given fnuction, and falling through into the calls is a useful difference
<TMA>
beach: on the other hand, the usual debuggers are concerned only with lines, they do not usually have more precise/granular locations
<beach>
TMA: Yes, that's why I am asking. If I wanted to be line oriented, I would emulate something like GDB.
<beach>
MichaelRaskin: Yes, indeed.
smurfrobot has quit [Ping timeout: 240 seconds]
<TMA>
and so there is usually no simple way to step into H but not into F or G given (f (g) (h))
<beach>
pjb: I might use the name STEP CALL so that the initial letter is different.
Kundry_Wag has joined #lisp
<beach>
TMA: si so sc
<pjb>
that said, perhaps we don't need to do anything special for the arguments: they're forms like others, so when we're stepping we'll stop in front of them like the others.
<beach>
Step In, Step Over, Step Call.
<MichaelRaskin>
TMA: if you are issuing each step command manually, you can just choose differently when H is evaluated
<pjb>
If we add the stop point at the end of each form to report result, we get automatically the stop before calling the function after evaluating all the arguments.
<beach>
TMA: SI would go to the beginning of (g), SO to the beginning of (h), SC would step into H.
<pjb>
From the debugger point of view, we could consider that all argument lists are wrapped in a call to list, so step out would be usable during argument evaluation, to stop before the call.
<beach>
I'll write down my conclusions tomorrow and submit them to y'all.
<pjb>
beach: one thing to be cautious about: the function can be determined before, or after (or perhaps more pathologically anywere in between?) the evaluation of the arguments. So the debugger cannot assume the function until it has evaluated all the arguments, if it wants to keep the same idiosyncrasies as the implementation.
<nirved>
what would plain STEP do then?
EvW1 has quit [Ping timeout: 245 seconds]
gigetoo has quit [Ping timeout: 264 seconds]
<MichaelRaskin>
I guess a thing from classic debuggers that could be useful is selecting a position and saying «do stepping until this becomes the execution position»
<nirved>
usually debuggers have two kind of "step", one for machine code, and another for the higher level mapping
smurfrobot has joined #lisp
<pjb>
(defun call (fname argforms env) (let* (fun (args (loop with fp = (random (1+ (length argforms))) for i from 0 for arg in argforms do (when (= i fp) (setf fun (fdefinitione fname env))) collect (evale arg env)))) (funcall fun args)))
<pjb>
conforming.
smurfrobot has quit [Ping timeout: 240 seconds]
rpg_ has joined #lisp
rpg has quit [Ping timeout: 268 seconds]
gigetoo has joined #lisp
smurfrobot has joined #lisp
fikka has quit [Ping timeout: 260 seconds]
Cymew has joined #lisp
eli_oat has joined #lisp
red-dot has quit [Quit: Going offline, see ya! (www.adiirc.com)]
klm2is has joined #lisp
smurfrobot has quit [Ping timeout: 264 seconds]
Cymew has quit [Ping timeout: 276 seconds]
Kundry_Wag has quit [Ping timeout: 264 seconds]
pierpal has quit [Quit: Poof]
karlosz has quit [Read error: Connection reset by peer]
pierpal has joined #lisp
bugrum has joined #lisp
karlosz has joined #lisp
<akkad>
xb
johnvonneumann has joined #lisp
johnvonneumann is now known as Guest18531
DemolitionMan has joined #lisp
rpg_ has quit [Ping timeout: 256 seconds]
light2yellow has joined #lisp
sz0 has joined #lisp
Arcaelyx_ has joined #lisp
Arcaelyx has quit [Ping timeout: 260 seconds]
eli_oat has quit [Quit: Leaving.]
Kundry_Wag has joined #lisp
vlatkoB has quit [Remote host closed the connection]
eli_oat has joined #lisp
trittweiler has quit [Ping timeout: 240 seconds]
rpg has joined #lisp
red-dot has joined #lisp
fikka has joined #lisp
wigust- has joined #lisp
rpg has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
wigust has quit [Ping timeout: 248 seconds]
<makomo>
beach: i've been thinking about your fcge (first-class global environments) idea and how you can implemement a sandbox with it
<makomo>
and i can't help but wonder why is it the case that so many dynamic languages that have EVAL usually promote the "EVAL is evil" thing
<makomo>
or rather, why don't they provide actual sandboxing functionality to make EVAL useful
<makomo>
so you can use the language itself to implement extensions and what not
<makomo>
why do so many languages skip this sandboxing part and just don't care?
<makomo>
from what i can see, even lisp is guilty of this
<makomo>
what is the point of EVAL if i can't bound its power
<MichaelRaskin>
So, you want Lua-style eval?
<dlowe>
it's not evil, there's just usually better ways than unbounded evaluation of code
<makomo>
(other than using it to EVAL stuff i control myself, rather than some arbitrary user input)
<Bike>
yeah, it's only evil in that it's a blunt instrument.
<makomo>
MichaelRaskin: so Lua supports that?
<on_ion>
lisp does it naturally, ie. macros; custom tailor-made EVAL.
<MichaelRaskin>
makomo: well, you can run something in an altered global environment
<makomo>
i see. are there any other languages that support that?
<Bike>
lisp family languages are the only ones i've seen that even treat environments as manipulable objects (and even then CL's are kind of shit)
<makomo>
dlowe: yes, but sometimes it's just required
<makomo>
on_ion: also ^
<makomo>
i mean, is it not?
<makomo>
even if you did implement your own DSL, you would still have to somehow dynamically compile and evaluate a user-written file
<MichaelRaskin>
Lua is minimalistic enough that whatever it can do with environment manipulation feels approximately as restricted as everything in Lua stdlib
<makomo>
and if this file contains (execute "rm -rf /"), you're screwed again
<makomo>
it boils down to this safety which you cannot control
puchacz has quit [Quit: Konversation terminated!]
<makomo>
you could walk the code and what not, but that's not really a good nor portable solution
<makomo>
MichaelRaskin: interesting. i thought lua might have something like this but i wasn't sure
<makomo>
are there any other languages that support switching out the global environment?
<MichaelRaskin>
You could look at something like Bussard
<MichaelRaskin>
It is a game that uses Lua sandboxing to do… everything
<makomo>
oh cool, i'll take a look
<makomo>
but only lua so far i guess then
<Bike>
beach's global environments aren't a complete sandboxing solution, also.
<makomo>
ah?
<makomo>
what is missing
<MichaelRaskin>
I guess truly standard definitions are still shared
<Bike>
Yeah, that's a problem.
<MichaelRaskin>
Which includes OPEN
<Bike>
For example if you call cl:write, it will refer to special variables, but it'll do that with whatever global environment it was compiled in
<makomo>
what does "truly standard" mean? defined by the common lisp spec?
<Bike>
well it's the same with anything.
shka_ has quit [Ping timeout: 260 seconds]
malice has quit [Remote host closed the connection]
Kundry_W_ has joined #lisp
<makomo>
Bike: meaning that if CL:WRITE was compiled in env A and now i'm in B and CL:WRITE is available to me, calling it from B will try to access which env's variables?
<Bike>
A's
<Bike>
i mean, for global bindings
<makomo>
and that would be bad because you couldn't for example rebind dynamic vars in B and have them affect what CL:WRITE would do?
Kundry_Wag has quit [Ping timeout: 268 seconds]
<Bike>
if you rebind them there's no problem, but if you don't it would use whatever value is global in A
<makomo>
would it also use B's globals if i defvar'd them in B (i.e. not just make a temp dynamic binding, but a global one)?
<Bike>
no. it would use A's globals because it was compiled so.
<makomo>
i haven't yet carefully read beach's paper, so maybe i'm missing something, but i don't get why. so if i'm in B and i do (let ((*something* 10)) (something-compiled-in-A)), something-compiled-in-A will see 10. but if i'm in B and i do (defparameter *something* 10) (something-compiled-in-A) then something-compiled-in-A will see whatever *something* is bound to in A?
<makomo>
or did i misunderstand
Jesin has quit [Quit: Leaving]
<Bike>
No, that's right.
warweasle_ has joined #lisp
comborico1611 has quit [Quit: Konversation terminated!]
pagnol has joined #lisp
<makomo>
Bike: hm, i guess that actually makes sense. so aside from the fact that defvars, defparameters, setfs, etc. might not affect certain functions, is there anything else?
<Bike>
any functions that call environment functions like find-class
<Bike>
so each environment needs its own make-instance, for example
Mutex7 has joined #lisp
<Bike>
strictly speaking, any function that signals anything uses the special variable *break-on-signals*
<makomo>
so every environment would need a complete copy of all the functions, global variables, etc. to behave properly?
warweasle_ has quit [Quit: Leaving]
<makomo>
so is a sandbox then hopeless or just tricky (but not as tricky as code-walking and similar) to do?
<Bike>
Just kind of annoying.
<Bike>
And this is mostly just the way CL is organized making it difficult.
<makomo>
i see
<Bike>
You could define a standard library where all the functions take a global environment as an explicit argument and use it scrupulously, and then just give each environment wrapper functions that call those with the environment.
<makomo>
oh hmm, so this is something that the implementation would do i guess?
eli_oat has quit [Quit: Leaving.]
<Bike>
I suppose.
<makomo>
so not only would the implementation have to support FCGEs, but if you wanted it to be actually usable, it would have to reimplement the whole stdlib to also take these env arguments and then create wrappers that delegate to these
charh has joined #lisp
<makomo>
these -> them*
kmurphy4 has joined #lisp
<Bike>
i guess alternately they could consult a global environment that's in a dynamic binding, which then has to be bound locally for any calls
<makomo>
that doesn't sound horribly bad, but would still require some work
<makomo>
Bike: hmm, right
<Bike>
Or you could force the sandboxed code to be in a nearly-CL that doesn't have variables like *break-on-signals* and can't use function designators and stuff.
rippa has quit [Quit: {#`%${%&`+'${`%&NO CARRIER]
<MichaelRaskin>
One of the problems with doing sandboxing without full implementation support and without implementing a transpiler from Common Lisp to Common Lisp is that you never know what expanding standard macros can leak
<makomo>
huh yeah
<makomo>
is a sandbox so much to ask for ;_;
<MichaelRaskin>
Well, maybe it is reasonable to do implement a self-transpiler as a Common Lisp macro library.
dented42 has joined #lisp
<makomo>
MichaelRaskin: what would something like that look like?
rpg has joined #lisp
<MichaelRaskin>
Basically, you would have a package where all the Common Lisp stuff is defined, but all the standard macros expand to something pre-vetted.
<MichaelRaskin>
For many things the HyperSpec gives semantically acceptable but inefficient expansions, maybe you should make sure that your macroexpand only gives expansions like this
<MichaelRaskin>
(compilation with optimisations could try making sure the expansions do not leak and using efficient ones whenever it is safe)
<MichaelRaskin>
Once everything is the wrappers you control, you make sure these wrappers also rebind all relevant global variables to use the desired FCGE contents
<MichaelRaskin>
And you make sure you use a reader that thinks this masquerade package is the real :common-lisp
<makomo>
oh, so just making sure that the macros' expansions don't leak then? when you said "self-transpilers as a Common Lisp macro library" i thought you meant something else (but i still don't know what you meant by that, i.e. what is self-transpiling here?)
Folkol has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]
<Bike>
for example, on sbcl, defun expands into a call to sb-impl::%defun
red-dot has quit [Quit: Going offline, see ya! (www.adiirc.com)]
<Bike>
rather than (setf sicl-genv:fdefinition)
innovati has quit [Quit: My MacBook Air has gone to sleep. ZZZzzz…]
red-dot has joined #lisp
<MichaelRaskin>
Well, you write in Common Lisp a set of functions and macros that allow you to compile Common Lisp (with your preferred environment treatment) to Common Lisp (with only standard-based assumptions, and probably some defacto standard extensions)
<makomo>
mhm
bugrum has quit [Remote host closed the connection]
<makomo>
i guess OS-level sandboxing is always an option
<makomo>
but that's not as convenient
andrei-n has quit [Ping timeout: 245 seconds]
innovati has joined #lisp
slyrus1 has quit [Quit: slyrus1]
Bike has quit [Ping timeout: 260 seconds]
hjek has left #lisp [#lisp]
shenghi has quit [Ping timeout: 264 seconds]
MichaelRaskin has quit [Ping timeout: 248 seconds]
<asarch>
How would you initialize a slot from a super class slot?
<phoe>
asarch: the slots are named differently, correct?
hjek has joined #lisp
<phoe>
if yes, SETF SLOT-VALUE inside INITIALIZE-INSTANCE :AFTER
innovati has quit [Quit: My MacBook Air has gone to sleep. ZZZzzz…]
lonjil has quit [Ping timeout: 276 seconds]
<asarch>
Thank you phoe
<asarch>
Thank you very much :-)
varjag has quit [Quit: ERC (IRC client for Emacs 25.2.1)]
msmith has quit [Ping timeout: 268 seconds]
LiamH has quit [Quit: Leaving.]
red-dot has quit [Quit: Going offline, see ya! (www.adiirc.com)]
fraya has quit [Remote host closed the connection]
MasouDa has joined #lisp
eli_oat has joined #lisp
eli_oat has quit [Client Quit]
hjek has quit [Remote host closed the connection]
light2yellow has quit [Quit: light2yellow]
sjl has quit [Quit: WeeChat 2.2-dev]
Achylles has joined #lisp
EvW has joined #lisp
pagnol has quit [Ping timeout: 240 seconds]
pierpal has quit [Quit: Poof]
pierpal has joined #lisp
red-dot has joined #lisp
mindCrime has quit [Ping timeout: 260 seconds]
Bike has joined #lisp
sjl has joined #lisp
sz0 has quit [Quit: Connection closed for inactivity]
innovati has joined #lisp
MasouDa has quit [Ping timeout: 256 seconds]
pagnol has joined #lisp
pagnol has quit [Read error: Connection reset by peer]
quazimodo has joined #lisp
Achylles has quit [Ping timeout: 256 seconds]
Khisanth has quit [Ping timeout: 240 seconds]
asarch has quit [Quit: Leaving]
Mutex7 has quit [Quit: Leaving]
TCZ has quit [Quit: Leaving]
Cymew has joined #lisp
Khisanth has joined #lisp
smurfrobot has joined #lisp
Cymew has quit [Ping timeout: 265 seconds]
robotoad has quit [Quit: robotoad]
Kundry_W_ has quit [Remote host closed the connection]
Kundry_Wag has joined #lisp
Kundry_Wag has quit [Remote host closed the connection]
Kundry_W_ has joined #lisp
Kundry_W_ has quit [Remote host closed the connection]
Kundry_Wag has joined #lisp
Kundry_Wag has quit [Ping timeout: 264 seconds]
Achylles has joined #lisp
Domaldel_2 has quit [Quit: Leaving]
<pillton>
Bike: Would copy on write work to solve the sharing of objects across environments?
mange has joined #lisp
<Bike>
if you had some ability to copy a function but change one of its constants, i guess
BitPuffin has quit [Remote host closed the connection]
smurfrobot has quit [Remote host closed the connection]
ckramer has joined #lisp
ckramer has left #lisp ["ERC (IRC client for Emacs 26.1)"]
<pillton>
Is it not a good idea to maintain a link between the lexical variable and the current global environment in situations like (let ((x 1)) (defun example () (incf x)))?
kmurphy4 has quit [Quit: kmurphy4]
karlosz has quit [Ping timeout: 256 seconds]
Kaisyu has joined #lisp
Pixel_Outlaw has joined #lisp
lumm has quit [Quit: lumm]
Kundry_W_ has joined #lisp
red-dot has quit [Quit: Going offline, see ya! (www.adiirc.com)]