freenode/#sicl - IRC Chatlog
Search
7:30:18
beach
But I keep thinking how close we are to extract at least part of Cleavir to a separate library.
7:31:36
beach
Once Clostrum is done, We can extract CST-to-AST, which then includes the AST definitions. To accomplish its task it would then use Eclector, CST, Trucler, Clostrum, and the CST-to-AST code.
7:32:09
beach
The only thing that needs to be decided is which part of the existing code counts as generally useful, and which part should be left as client configuration.
7:34:01
beach
In that extracted library, we could also supply default versions of some of the macros like DEFUN, DEFMACRO, and the simple ones like WHEN, UNLESS, etc.
9:38:33
jackdaniel
beach: what should we do with function-unbound? remove it from the specification or leave it be?
9:40:09
jackdaniel
OK, I think that its description should be clarified in that case, because based on the rest of the specification it is not clear, how the "client code can use the return value of this function to determine whether function-name is unbound"
9:41:22
beach
OK. How about, "if the value returned by this function is EQ to the CAR of the CONS cell returned by FUNCTION-CELL, then the function is unbound"?
9:42:30
jackdaniel
OK, I think that you've mentioned some change in the repository (I've suggested that you should pull first) – I don't see that change, so I suspect that you did not push
9:48:03
beach
Oh, and I would like to you keep the protocol system(s) and package(s) separate from those of the implementation. The idea is that a client might use the protocol, but with an implementation that is adapted to specific needs.
9:48:50
jackdaniel
there is a system clostrum, which contains the protocol, and clostrum/virtual for example implementation
9:49:20
jackdaniel
there are two packages in the system clostrum: clostrum and clostrum-implementation, first only exports symbols while the second one defines protocol classes and functions
9:54:19
jackdaniel
I think that a similar clarification should be made to a function variable-unbound
10:33:19
jackdaniel
I have a question after all. it is longer than one line, so I've pasted it: http://turtleware.eu/static/paste/fe810dee-function-inline.txt
10:35:20
jackdaniel
well, more a suspiction that function-inline specification is vague enough to allow undefined behavior
10:45:19
jackdaniel
(underlying assumption is that inline information is not stored with a function and that fdefinition does not modify that information because it is not specified to)
12:02:11
jackdaniel
the specification of (setf special-variable) has a typo, its lambda list is (value symbol environment init-p), it should be (value client environment symbol init-p) -- most notably it lacks client, but also the argument order is not consistent with other operators
12:08:55
jackdaniel
right, but should we preserve the inline information after the function-name becomes unbound?
12:09:04
beach
So when the compiler sees (defun f ...) it must be able to query the environment and get back INLINE so that it can save whatever information is necessary.
12:13:12
beach
But now I am thinking that we might need a way for the compiler to recover not only WHETHER the function is declared inline, but also the inline information associated with it.
12:15:02
jackdaniel
so it seems to indicate, that the proclamation applies to a function name, not a particular function
12:15:17
jackdaniel
in other words, there is nothing what would warrant removing such information when the function is undefined
12:15:50
beach
We define two more generic functions inline-information and (setf inline-information).
12:17:55
beach
And when the function is made undefined, the inline information is erased (NIL), but not the flag.
12:18:40
beach
If it returns INLINE, the compiler will then consult INLINE-INFORMATION, and use that information only if it is not NIL.
12:18:42
jackdaniel
and that new functions would belong to the run time environment? or to the compilation environment?
12:19:10
jackdaniel
the former I guess, because the function may be defined in a different compilation unit
12:22:27
beach
If, when the compiler sees (defun f ...), FUNCTION-INLINE returns INLINE, then the compiler must nevertheless save inline information (like an AST) about the function, so that it can be inlined when the compiler sees a call to f later on.
12:24:39
beach
It is possible that (setf function-inline) was invoked on the run-time environment completely outside of any compilation.
12:25:34
jackdaniel
can't the compiler use the compilation environment's parent to access that information?
12:25:38
beach
The information in the compilation environment must take priority over the one in the run-time environment.
12:26:38
jackdaniel
so in other words, both run-time environment and compilation environment participate in the inline-information protocol?
12:26:40
beach
Because if the compiler then sees (eval-when (:compile-toplevel) (defun g () .. (f ...))) then F would be inlined.
12:28:15
jackdaniel
but function-inline belongs only to run-time environment and that information is preserved across function redefinitions
12:31:22
jackdaniel
I agree; for now I'll leave it defined as it is shown in the paste above, in the meantime I'll also try to think about inlining
12:35:06
pjb
jackdaniel: Not really. Thinking is not always easy or automatic. Sometimes you have to apply yourself to it. And sometimes you're distracted from it, so it's hard.
12:48:05
jackdaniel
I have another question: using the function special-variable, how am I supposed to decide, whether the symbol is a special variable or not?
12:48:36
jackdaniel
consider i.e that I'm defining a special variable without a value, i.e (setf (special-variable client env 'my-symbol nil) nil)
12:49:43
jackdaniel
how is it different from calling (special-variable client env 'my-not-so-special-symbol) ;?
12:50:16
jackdaniel
beach: should I consult doubts like that or try to "fix" the specification on my own?
12:51:57
beach
Whatever it does to my context, it is important that we discuss those issues, do don't fix anything unless you are absolutely sure.
12:56:17
jackdaniel
I had a doubt if it should be the first value, but after a second of consideration it sounds right, because the primary value should not be nil if it is the special variable
12:56:48
jackdaniel
(and if that flag went as the third value, then this assertion could be invalid when there is no value or the value is nil)
12:57:15
beach
Yeah, and a compiler might want only the special/no-special information, so that should be first.
13:16:16
beach
Hello Bike. You might want to participate in the discussion about these scenarios that we are contemplating with jackdaniel.
13:17:17
beach
We haven't come up with many yet, but yes, you can check that we are on the right track if you have the time.
13:19:27
jackdaniel
I will be afk for ~1h, but before I do that I want to suggest one more operator: constant-variable-p
13:19:53
jackdaniel
the reader constant-variable signals an error if symbol does not denote a constant variable
13:20:52
jackdaniel
in principle that could be defined as (and (boundp symbol) (not (special-variable symbol)) (not (symbol-macro symbol))) -- pseudocode, but that would be quite harsh on the protocol user
13:21:20
jackdaniel
we could, but then we should change the specification, that (constant-variable …) signals an error when there is no such constant
13:39:42
beach
Here is a scenario: The compiler sees a call to function F, so it calls the Trucler function DESCRIBE-FUNCTION. The object returned by Trucler contains the "flag" inline/notinline/nil and if it is INLINE, the object must also contain some data, like an AST for the compiler to use for inlining.
13:41:10
beach
Ultimately, if it is not a lexical function, DESCRIBE-FUNCTION is called on the compilation environment. So the client must define a method on that function. How does the client implement that method?
13:42:15
beach
Well, it starts by calling FUNCTION-INLINE on the compilation environment. Because if there is a top-level (DECLAIM (INLINE ....)) then FUNCTION-INLINE returns INLINE or NOTINLINE.
13:42:56
beach
If there is no such information in the compilation environment, it is possible that the function exists in the evaluation environment or in the startup environment.
13:44:18
beach
It is part of the startup-environment if the programmer has (proclaim '(inline ...)) before starting the compilation.
13:45:49
beach
And it is part of the evaluation environment if the programmer did (eval-when (:compile-toplevel) (proclaim '(inline ...))).
13:47:19
beach
So the function FUNCTION-INLINE first consults the compilation environment and then its parent, and then the parent of the parent, etc.
13:49:07
beach
Now, let us imagine what the method on the Trucler function DESCRIBE-FUNCTION does if FUNCTION-INLINE returns INLINE. It must then find the inline data (say AST) and store it in the FUNCTION-DESCRIPTION object.
13:50:53
beach
That will happen if the function F was defined using DEFUN in the same compilation unit, because then, F does not get created at compile time, but inline data for it must be stored, and that is what the compilation environment is for.
13:52:16
beach
If the inline data is not found in the compilation environment, it is possible that there was (eval-when (:compile-toplevel) (declaim (inline F)) (defun F ...)...) during compilation. So then the function F got defined in the evaluation environment.
13:52:59
beach
It seems reasonable to me that the inline data should then be associated with the function OBJECT, as opposed to being a separate entity the way it must be in the compilation environment.
13:53:56
beach
But client code decides how functions are represented, so Clostrum can't decide how that data is (are?) stored.
13:55:05
beach
So I suggest that Clostrum define a default method that returns NIL for INLINE-INFORMATION on the run-time environment.
13:56:14
beach
SICL will supply a method that does (sicl-mumble:ast (clostrum:fdefinition 'F environment)) because it will have a slot for the AST in the function.
13:56:38
jackdaniel
I think that clostrum (a protocol, as opposed to the example implementation), should not define the method at all - it may be accessible from the fdefinition or from somewhere else, but why a default empty method?
13:57:06
jackdaniel
it should only define a generic function and a terampoline from the evaluation environment
13:58:20
jackdaniel
from the specification I understood, that the evaluation-environment-mixin implements the same protocol as the run-time environment, but all methods are (or (call-next-method) (call-this-method (parent env)))
13:59:59
jackdaniel
I imagine, that as a rule of thumb it works fine, and if the client defines their own method then they can overwrite the default behavior
14:00:39
beach
Also, we don't have to be perfect from the start. Let's not let perfection get in the way of something reasonable.
14:01:15
jackdaniel
I'm not sure if you approve of such solution, but I've defined macros define-operator and define-accessor, which record run-time-environment protocol methods (and add some sanity checks to arguments), and then generate trampolines automatically
14:01:24
jackdaniel
as you can observe here: https://github.com/s-expressionists/Clostrum/blob/master/Code/clostrum.lisp
14:06:18
jackdaniel
so to summarize: we should update the specification wrt special-variable and constant-variable (return values), specify the function function-inline for the compilation-environment, and specify the function inline-information for both run-time-environment (and by inheritance, to evaluation-environment-mixin) and compilation-environment, is that right?
15:07:48
beach
This is a very interesting exercise, i.e. discussing the details of the different environments and their roles. In the end, I think this will be great! And by "this" I mean Clostrum, but also the use of Trucler, CST, Eclector, AST, and CST-to-AST for this entire phase in the compilation process.
15:11:05
beach
Speaking of which, I am thinking about what to do for compile-time EVAL. I think the idea I showed Harag for sandboxing will work. Since the compilation is done by CST-to-AST, we can invoke CST-to-AST recursively on the code to be evaluated during compilation, thereby producing an AST.
15:12:19
beach
Then we can translate that AST to Common Lisp code in a trivial way, except that a few things like FDEFINITION-AST will be translated into clostrum:fdefinition with the evaluation environment as its argument.
15:13:59
beach
Since the AST no longer has macros in it, it will just call functions. The client can fill the evaluation environment with whatever definitions of those functions it finds appropriate.
15:44:26
jackdaniel
since we've agreed that function-inline is not erased when the function is undefined, should it return error when it is not defined?
16:05:08
jcowan
I have a lot of sympathy for the ISLisp position that only a subset of the language is available in macros, though the subset is not very precisely specified.
16:11:05
jackdaniel
I don't like the idea of islisp at all, it brings nothing new to the table (it is basically a subset of common lisp)
16:11:19
jcowan
Yes: "The set of usable operations [in a macro expander function] is restricted to simple data structure creation and manipulation; those operations are forbidden that cause side-effects to the environment (such as I/O to the terminal), to externally accessible data structure (such as a modification to the property list of a symbol), or to the macro form itself." (clause 16)
16:11:43
jackdaniel
(unlike i.e eulisp which was being specified around the same time, never standardized though)
16:12:16
jcowan
ISLisp is intended to be non-reflective: in particular, there is no EVAL or COMPILE at runtime. However, you do need an EVAL at compile time in order to handle macro expanders.
16:12:17
pjb
jackdaniel: ISO Lisp has some cleanup that proponents of CL21 would like to have in CL…
16:14:28
jcowan
The idea of Lisps that are static (not in the sense of type, but in the sense of not being malleable at runtime) is an interest of mine.
16:18:04
jackdaniel
pjb: it is only syntactic sugar, they are special variables with separate forms and a namespace. I can see though that someone might like that. thanks
16:46:18
jcowan
After all, there are people like the author of Picolisp who think that CL betrays the spirit of Lisp malleability because you cannot mutate a function object at runtime, as you can in Elisp.
16:46:49
jcowan
So staticness is a continuum, with Picolisp almost at one end (you can even mutate a bignum if you insist)