freenode/#lisp - IRC Chatlog
Search
6:53:52
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
6:54:10
makomo
usually the stuff that's in the glossary is defined somewhere in the standard explictily
6:54:59
makomo
i think i understand the concepts because it's not so different from C++'s storage duration for example
6:56:06
makomo
White_Flame: oh i remember that conversation from the other day but i wasn't following closely. where does it do that?
6:57:40
White_Flame
indefinite extent means that the language mechanics don't make a reference undefined
6:57:57
spiaggia
makomo: There is no mention of thread-local in the standard, simply because there is no mention of threads in the standard.
6:58:20
makomo
White_Flame: yup. i think of it as just because something that has been malloc'd but never free'd :-)
6:59:01
White_Flame
although the GC will eliminate non-referenced objects, which might fall in the same technical vocabulary
7:00:34
makomo
White_Flame: hm so, this implies thread-locality only if we assume the existence of threads and their usual behavior right?
7:01:07
White_Flame
"an extent whose duration is bounded by points of establishment and disestablishment within the execution of a particular form. "
7:05:33
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?
7:09:53
hajovonta
makomo: I haven't hold it yet, first my colleague will do it on the topic of Prolog, this Wednesday as planned
7:11:23
hajovonta
but Erlang and Prolog are also being teached on our universities, so Lisp is the most alien of all of them
7:12:20
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
7:12:39
hajovonta
makomo: also I don't have pointers (but Google will surely help me out with that :)
7:12:47
makomo
it's probably only just a subset. writing a serious prolog implementation would certainly take more than 50 lines.
7:15:52
White_Flame
the thread environments could be considered overlays onto the shared global environment
8:07:00
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.
8:07:44
makomo
ah, my question wasn't formulated very well. i meant to ask does it interact with :compile-toplevel and :load-toplevel
8:09:41
makomo
and the fact that EVAL might perform implicit compilation doesn't mean anything right, i.e. it still only fires with :execute?
8:10:38
beach
makomo: Yes, if EVAL does implicit compilation, it must still respect the restrictions of EVAL in the standard.
8:10:47
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
8:16:56
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
8:18:09
jackdaniel
(for instance you expect, that your defun will be visible to other functions in your file)
8:22:38
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
8:23:05
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
8:29:06
jackdaniel
makomo: that'd require VFS which is not part of CL standard (and not implemented in any implementation so far afaik)
8:29:19
jackdaniel
you may create a macro, which takes your string, writes it to temporary file and compiles it with compile-file
8:29:32
makomo
jackdaniel: that's one way to do it, but what about the standard defining something like COMPILE-STRING?
8:32:00
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
10:51:04
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.
10:52:10
fm4d_
Why the 'var' variable behaves as if it is a part of closures surrounding the function.
10:53:40
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.
11:01:18
beach
And, technically, it is not a "closure", since it does not close over any lexical variables.
11:01:45
beach
The function TEST in the example is defined in the global environment, also known as the null lexical environment.
11:04:05
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.
11:04:51
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.
11:06:54
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).
11:08:04
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.
11:09:03
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.
11:09:43
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.
11:13:11
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.
11:14:12
beach
After all, SBCL with SLIME is able to evaluate forms relative to a lexical environment.
11:14:45
beach
You are still not protected from the compiler removing variables that are not lexically apparent.
11:17:20
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)
11:17:26
beach
"Evaluates form in the current dynamic environment and the null lexical environment."
11:34:48
lukego
recommend a reasonably portable/stable/efficient library for doing asynchronous sockets/timers ("state machine style")? cl-async? iolib?
12:19:47
makomo
hajovonta: a thing that you could do is inject a let into the code that is being EVAL'd
12:20:29
makomo
so instead of (eval some-code) you would have (eval `(let (... bindings ...) ,@some-code))) :-D
12:22:08
hajovonta
the problem is essentially (let ((x 1)) (eval (read-from-string "(setf x 2)")) x)
12:24:17
makomo
but yeah, that x is then not visible to the environment that called EVAL in the first place
12:25:24
hajovonta
but, as you say, it works: (defparameter x 1) (eval (read-from-string "(setf x 2)"))
12:27:04
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)
12:27:25
makomo
so that effect is persistent because that hash table is floating somewhere in the lisp image
12:30:07
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
12:30:24
makomo
rather than having to say something like "(gethash 'a (variables *current-object*))" or something
12:30:50
makomo
i.e. so it doesn't have to use any implementation details of the object language implementation
12:31:30
makomo
so i inject LETs like "(let ((a ...thing with *current-object*...)) ...actual code...)"
12:32:13
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
12:33:20
makomo
i don't know whether there's a "better" way or if we should even be bothered by this way
12:47:22
xificurC
I just got a question from colleagues what does "prog" stand for in progn or prog1, anyone knows?
12:50:14
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
12:51:52
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
12:55:37
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.
13:02:52
nowhere_man
Has anyone written a macro that contains a defmacro? I'm really struggling here.
13:05:23
nowhere_man
Writing the "first-level" macro is very easy: (defmacro {lazy} ((&rest args) &body body) `(make-instance 'lazy-function :fun (lambda ,args ,@body)))
13:05:46
nowhere_man
Now I'd like to write several identical macros with the name and class changing
13:06:07
nowhere_man
shka: they are straight up mysterious, I've been playing with them for some time now
13:07:49
nowhere_man
and in this case, I would have liked to understand how I can manage to pass the class as a symbol
13:10:02
xificurC
(defmacro uber-lazy (mname class) `(defmacro ,mname (args &body body) `(make-instance ',,class :fun (lambda ,args ,@body))))
13:10:42
xificurC
(defmacro uber-lazy (mname class) `(defmacro ,,mname (args &body body) `(make-instance ',,class :fun (lambda ,args ,@body))))
13:13:47
nowhere_man
I'd like to be able to do both (make-function-maker {lazy} 'lazy-function) and (make-function-maker {other} (class-of something))
13:15:38
nowhere_man
It works like this with just class names: https://plaster.tymoon.eu/view/805#805
13:16:34
makomo
i was just about to ask, wouldn't that require for this defmacro to not be at the top-level
13:21:04
Bike
I mean, and you'll have to do (make-function-maker lazy 'lazy-function) instead of just (make-function-maker lazy lazy-function), of course.