freenode/#lisp - IRC Chatlog
Search
23:09:49
drmeister
How does write-to-string decide what width of character string its supposed to write to?
23:38:22
pillton
aeth: Was this a question about specialization-store? "All that's really missing is a defmethod that supports inline and classes for keyword/optional (which iirc are not supported, possibly because of the ambiguity in a straightforward attempt)"
23:55:33
mega_beginner
Out of curiousity, is locality of reference a concern in lisp when writing code that usually requires it in C/C++/Fortran (insert "fast" language here) (such as matrix multiplication)?
23:59:40
mega_beginner
I guess I have a nagging misunderstanding of how things operate at a lower level in lisp short of dissassembling everything.
0:09:25
White_Flame
yeah, disassembly is great to learn from, especially when it comes to performance, or simple curiosity of how things are implemented
0:10:03
White_Flame
I have a (asm (..params..) ..body..) macro which disassembles a lambda with optimizations cranked, just to see what SBCL can pull off
0:12:33
mega_beginner
Next thing I'll have to read up on is incremental compilation, and how things are referenced in light of that technique (compiled to raw address label or hash table lookup for example). I have to leave though
1:18:39
epony
I'm interested at what point it starts getting "ecosystem" before other discussion points are closed.
1:19:18
aeth
makomo: Accessors aren't just methods defined by defclass automatically. They're anything with a reader and/or writer. CAR is an accessor and e.g. WITH-ACCESSORS should work with it.
1:22:41
pillton
aeth: Ok. The return type in specialization-store is needed to allow compile-time optimizations to occur when one store function is composed with another.
1:23:23
aeth
pillton: My original point in full, which I didn't communicate well (but no one was really responding to it and I didn't want to flood the channel with corrections) is that there are effectively three incredibly similar operations.
1:23:59
aeth
pillton: It's pretty easy to write a macro on top of defun to handle things that otherwise would require declare/declaim/etc. At the very least, it's the easiest of the three to do.
1:25:07
aeth
The thing that's missing, then, is CLOS defmethod-style dispatch that's "completed" with inlining and with full support for keyword/optional
1:25:59
pillton
This is where I get lost. specialization-store supports dispatch on optional and keyword arguments.
1:26:55
epony
a surgeon is called on an emergency, a relative is accepted in emergency in a different location
1:30:19
aeth
epony: Three ways to do type-like things. function-with-types, type-dispatch, and class-dispatch.
1:30:42
aeth
Function-with-types can be done with type declarations where supported. Clumsy syntax, but you can make a macro handle it fairly easily.
1:31:14
pillton
aeth: It isn't because defmethod dispatches on class where specialization-store dispatches on type. Types cannot be ordered like classes so specialization-store cannot give the same guarantees during dispatch.
1:42:30
epony
now, back to basics, it is imperative that you accept a third operator in a linear clause
1:42:36
pillton
aeth: One could create a metaclass for specialization store which is only defined for types which are classes and dispatches according to CLOS' rules. The only difference between CLOS and specialization store is the way it handles initforms for optional and keyword arguments.
1:43:25
aeth
epony: This is a technical channel. If you're using something like Google Translate, what we're saying is going to be lost in translation.
1:43:44
aeth
Words have very precise meanings here, some of which are specific to just Common Lisp as defined in the HyperSpec.
1:44:13
aeth
mfiano: I'm not sure if epony is drunk/on-drugs, bot, using Google Translate, or crazy.
1:48:06
epony
I'm curious, why do you respond so slow, aeth and pillton... if you're happy doing something else but thinking.
1:48:56
aeth
pillton: Oh, in case you're interested, I finished porting math/vector.lisp to specialization-store. https://gitlab.com/zombie-raptor/zombie-raptor/blob/b9a759557e47aeef4b3060b8a3b0290f23db6ed7/math/vector.lisp
1:48:58
pillton
aeth: The major difference between CLOS and specialization is that the initforms are evaluated by the store function and are used to determine the specialization.
1:49:31
epony
obviously I am pointing to a weak position and you are stuck on "if you don't contribute"
1:50:32
aeth
pillton: I base every vector function on an inline function on multiple values to simplify the definition of the specializations. I then wrote two macros to define the three common specialization patterns for the file (create a new vecn, replace the contents of a given vecn, or just directly work with the body because it's not returning a vecn)
1:51:44
pillton
aeth: Nice. I will have to look in to it. To see if anything can be added to my template-function system.
1:52:35
aeth
oh, there's two more pieces of information to understand that file. array-of-n is just a convenience function to either get multiple values from an array or replace an array with given multiple values (this composes rather nicely, except for the length having to be specified)
1:53:02
aeth
and define-function is just syntactic sugar over the declarations of defun to make specialization-store more of a drop-in replacement
1:53:47
aeth
I think it costs one line of assembly to do things this way (multiple values), but it makes the implementation so elegant and trivial that I went with it.
1:55:49
pillton
aeth: Great. I designed specialization store for these kinds of problems. I am glad it is working out for you.
1:59:25
aeth
pillton: Just to check because it's been a while, an inline inlines the whole thing (assuming type declarations are used), but a named specialization will be able to inline the function call (again assuming declarations), right? (Unless it's both named and inlined, in which case it's just like inline)
2:09:51
pillton
aeth: It doesn't inline the function call. It avoids the dispatch at runtime by replacing the store function call with a function invocation.
2:10:00
pillton
aeth: https://github.com/markcox80/specialization-store/wiki/Tutorial-3:-Compile-Time-Support#named-specializations
2:13:57
mfiano
It might solve my dispatching performance concerns for my math library. The last couple says I've been trying to write something with compiler macros and introspect-environment to solve that...looks like this is already a thing.
2:15:42
pillton
mfiano: It is meant for maths problems. These are the types of problems I use it for. https://github.com/markcox80/template-function/wiki/Motivating-the-Template-Function-System
2:23:06
epony
and these people are the people that you trust commanding the future enterprise of corporate success
2:33:50
aeth
pillton: Are any of your math projects public? I'd be interested to see something that uses specialization-store and/or template-function.
2:59:51
epony
beach please let us have a quick talk, in a case of a third operative who do you victimise?
3:18:31
pillton
aeth: No not yet. I started work on a matrix/container library which uses it. A lot of the effort there is to do with iterating over the elements.
3:19:57
pillton
aeth: I haven't had much time to do anything since (i) the birth of my third child and (ii) I no longer use CL at work.
3:30:17
pillton
aeth: It would be good to look in to partial specialization as an alternative to what we are doing.
3:32:19
pillton
aeth: One aspect I like in template-function is the ability to request a specific specialization. It would be good if you could do this for arbitrary functions.
3:37:23
aeth
pillton: By partial specialization, do you mean this? ((v1 vec3) v2) instead of this? ((v1 vec3) (v2 vec3)) in e.g. vec= (which is probably where it would make the most sense), with e.g. an etypecase to handle the vec2, vec3, and vec4 cases in the specialization defined for v1 being vec3?
3:38:55
pillton
aeth: Yes. Something like, take this lambda and produce a new lambda which is optimized for arguments of this type.
3:39:03
aeth
That would reduce 9 definitions down to 3 in https://gitlab.com/zombie-raptor/zombie-raptor/blob/b9a759557e47aeef4b3060b8a3b0290f23db6ed7/math/vector.lisp#L247-274
3:39:15
aeth
(and the 3 would be one top-level form in my very specific case where I define all three at once)
3:41:37
pillton
Yeah. I think the problem with math is that the user has all of the information e.g. floating point precision, argument ranges etc. Specialization store still tries to go down the path of making the library provide everything.
3:44:25
aeth
Ah, yeah, precision. I haven't gotten into that yet. Right now, I assume single-float. I'll have to double the types (dvec2, dvec3, and dvec4) for double float. The problem with doubles is that multiple-values no longer becomes an elegant simplification because they're boxed and cons unless they're already part of an array.
3:45:06
aeth
Where I do work with double-floats right now, I have to make sure they're in an array or typed struct slot and then if I return a scalar value, I coerce it to single-float first.
3:46:09
aeth
This would mess with the dot-product, but it's inline so the user probably has the same freedom to do that if they don't want to cons the result.
3:59:27
aeth
I can see how precision can make specialization-store problematic. Now you need (dvec3 vec3) and (vec3 dvec3) versions for each consing function, making a total of 4 (the other two would be two vec3 and two dvec3). Worse, a destructive, non-consing vrsion needs dvec3 and vec3 *destination* vectors for at least the two mixed ones (total so far, 6) if not the other two (now, 8)
4:00:27
aeth
So it goes from 2 versions (pure and destructive) to 4+8=12 versions if you can mix double and single precision vectors
4:02:11
pillton
This is the problem template-function tries to solve. You specify it once and generate the code on demand.
4:04:09
pillton
The compile time functionality of the iteration component of the matrix library I was talking about before is important as well.
4:06:46
mfiano
It seems to take 1s for 1 million iterations of a simple inlined specialization, whereas a non-inlined function with the same body takes about 0.2s
4:34:15
aeth
pillton: Would there be some way to make specialization-store aware of inferred types in SBCL?
4:40:16
pillton
I don't know how SBCL infers types. I don't know the requirements of the type inferrer's transformations either.
4:43:28
aeth
asarch: defstruct is, in my experience, useful for two things: (1) quickly defining accessors for a sequence (this is a special kind of defstruct) or (2) creating a data structure where :type for the slots is important.
4:44:20
aeth
Implementations don't really respect :type in CLOS slots. CCL is the only one in my testing that errors by default when you violate :type with a CLOS object. SBCL does so with (debug 3)
4:48:12
MichaelRaskin
beach: yes, it seems that it basically has everything that is needed to declare it «implementation-side support for debugger». Except performance, probably.
4:52:54
MichaelRaskin
Well, there are two sides of performance (time to walk/compile and time to run) and I have bad feelings about both, although it might still be better to have an option to step/trace than not to have it at all
4:53:37
beach
asarch: Presumably, the main advantage of structs is that the implementation can represent them more efficiently than it can represent standard objects, because standard objects require an indirection so that they can be redefined. However, that advantage is also the main disadvantage in a language such as Common Lisp, because existing instances may not be possible to update when the struct definition changes.
4:55:15
beach
asarch: And that's a major inconvenience for people who work with images that execute for a long time. For example, in SICL, the plan is to implement structure instances with an indirection header as well. As a consequence, structs in SICL will have neither the advantages nor the inconveniences of structs in other implementations.
5:03:17
makomo
aeth: i just saw your comment about CAR being an accessor as well and being able to use it with WITH-ACCESSORS. is that true though?
5:04:36
beach
WITH-ACCESSOR merely introduces local symbol macros that can then be used as aliases for calls to the accessors.
5:05:20
makomo
beach: mhm, just saw the equivalent expansion in clhs. thought i saw WITH-SLOTS somewhere for some reason
5:05:48
makomo
so then the proper terminology for a CLOS accessor would be "slot accessor" or something similar?
5:06:56
aeth
makomo: The only catch afaik is that the accessors for WITH-ACCESSORS have to be of the form (foo x). e.g. AREF is an accessor and can't be used with WITH-ACCESSORS in most cases. (0D arrays exist)
5:08:19
makomo
the clhs is a bit misleading though. the "syntax" part at the top talks about "slots" and "instances"
5:09:34
makomo
so now how can we be sure that the fact that CAR and others work with WITH-ACCESSOR isn't just a consequence of the implementation via SYMBOL-MACRO? :-)
5:09:39
aeth
makomo: It is incredibly misleading. http://www.lispworks.com/documentation/HyperSpec/Body/m_w_acce.htm
5:10:07
aeth
I go there, I click on slot, and it defines it as: "slot n. a component of an object that can store a value. " http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_s.htm#slot
5:10:31
aeth
Especially because its example for object is CONS! http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_o.htm#object
5:10:47
makomo
beach: oh. i always read those parts at the bottom as "this is how it *might* be implemented"
5:11:27
makomo
and also "any extra functionality that we accidentally added by using a "wider abstraction" is not to be relied on"
5:11:42
beach
makomo: Also, take not of good terminology. A CONS cell is definitely a CLOS object if there every was any definition of that term.
5:13:33
beach
makomo: If you want to distinguish an instance of a standard class from other instances, then the correct terminology is "standard object".
5:15:45
makomo
beach: when you say "standard class" and "standard object", are you referring to STANDARD-{CLASS,OBJECT} or are you just using the term casually?
5:16:31
makomo
so then "instance" there refers to classes themselves, since they're object as well, right?
5:16:45
beach
makomo: But the terms "standard class" and "standard object" are also defined in the glossary.
5:19:45
beach
makomo: Not that the expression "A is a B" means that "A is an instance of the class B", so "A is a standard object" means that A is an instance of the class STANDARD-OBJECT as the glossary explains.
5:24:15
makomo
beach: but not all of these exist within the CLHS? for example, CLASS' precedence list doesn't contain SPECIALIZER
5:24:53
beach
But the Common Lisp HyperSpec also explicitly allows intermediate classes in the precedence list.
5:28:32
makomo
beach: is there a class which is its own superclass? is that even valid? i recall that an instance of a class can only be instantiated if all of its superclass classes are defined, but the class itself can be defined without the superclasses being defined yet -- i'm not sure if this in any way inhibits tricks like those?
5:29:23
makomo
because it's stuck in my head that i saw such a class somewhere, but i think it was just that i confused it with the first member of the class precedence list
5:30:01
beach
makomo: Yes, the class precedence list always starts with the class itself, by definition.
5:32:03
makomo
beach: huh, that isn't easy to think about. there are multiple meta layers here since STANDARD-CLASS itself is a metaclass right?
5:33:15
beach
But, think about it this way: Every object must be an instance of some class, and that includes classes. Therefor, there must be a cycle somewhere in the class->metaclass relation.
5:33:50
beach
makomo: The way they decided to do that is that the metaclass of STANDARD-CLASS is STANDARD-CLASS.
5:36:52
makomo
beach: there's a footnote in one of the early pages in the book that says that "self-referentiality is not essential to the basic notion of the metaobject protocol"
5:37:16
makomo
by "the basic notion", do they mean the availability of a meta interface, i.e. being able to customize the implementation itself?
5:37:35
makomo
while the "self-referentiality/reflective" part is just a characteristic of how the meta interface itself is implemented?
5:38:40
makomo
beach: by self-referentiality i think they refer to the fact that objects within the system represents parts of the system that implements them
5:38:54
beach
That might be true. But the combination of the two rules 1. A class is also an instance of a class, and 2. Every class has a metaclass, then I think you automatically have a cycle.
5:39:31
mfiano
pillton: Yeah, specialization-store for _library_ math code seems useless to me, since types aren't known at compile time without users annotating them. I see the utility in the library, but I don't think there is any for me :)
5:39:58
makomo
beach: yeah i mean, perhaps you could invent some other way of customizing a CLOS that doesn't utilize CLOS itself
5:40:48
beach
You can use the same mechanisms that the application programmer uses in order to implement CLOS itself.
5:40:54
makomo
they later say, but i never understood this part, "In on-going work that extends the ideas presented in this book, we are adding a metaobject protocol to Scheme, but we are using CLOS (not Scheme) as the language for expressing adjustments, so issues of self-reference don't arise."
5:42:40
makomo
although the word "metaobject" then loses its meaning, doesn't it? since the metainterface is now implemented in some other manner
5:44:21
makomo
beach: also, the fact that AMOP uses CLOS itself while implementing CLOS can be a bit confusing sometimes, because you don't know whether MAKE-INSTANCE just refers to a function they haven't defined yet or to the MAKE-INSTANCE of the host CLOS
5:49:32
beach
makomo: The book kind of assumes that everything is already in place and works as expected. They do not discuss bootstrapping much at all.
5:50:04
beach
makomo: The PCL implementation (which is theirs too) kind of assumes a CLtL1 Common Lisp implementation and they add CLOS to that.
5:50:51
beach
SICL, on the other hand does not start with a CLtL1. It assumes a fully conforming host implementation that also includes the MOP.
5:52:44
beach
Other implementations need a different notation for classes early in the bootstrapping process.
5:53:44
makomo
it's still not clear to me how you break free from the shackles of the CL implementation that's hosting you
5:54:47
beach
But they are implemented as standard classes, so I can load their definition into SBCL and use it.
5:55:41
makomo
beach: true, but SBCL itself can't use them right? the compiler you're talking about is SICL's compiler (written in CL as well)?
5:56:03
beach
This one of my favorites from other implementations (in this case ECL): (defparameter +standard-class-slots+ (append +class-slots+ '((optimize-slot-access) (forward))))
7:48:46
verisimilitude
I think it's self-evident why this is bad, but I'll explain; you claim that it opens you up to package interface changes; not only is this rather rare for a Common Lisp library, practically, but I fail to see how this is worth the horrible inconvenience when all that would be needed is to test the program against the latest version of a library, which is likely to be the last version, since the package likley hasn't been updated.
7:50:05
verisimilitude
I don't find it good practice to give advice on Common Lisp that amounts to ``Don't use this feature at all.''; it's not C++.
7:52:29
xificurC
just shows how incompetent beach is, can't even defend his own words, right verisimilitude?
7:52:31
MichaelRaskin
I would say in general the advice given by beach is often a bit idealistic. This reduce the usefulness of defending it against cynical crticism (obviously the library will never be updated anyway)
7:53:28
jackdaniel
rule of he thumb is not engaging in discussions with people who plan to argue (for a sake of arguing)
7:54:13
verisimilitude
Well, some people get offended if you call people a male and get it wrong, even though I'd wager almost everyone here is.
7:54:16
jackdaniel
while many advices shared by people may be arguable, calling them plain wrong is, ekhm, wrong ;)
7:54:36
verisimilitude
One dumbass here threatened me over a Rust joke, which was amusing, but stupid.
7:55:29
verisimilitude
Anyway, I meant that many Common Lisp libraries are simply finished, MichaelRaskin.
7:56:52
MichaelRaskin
As the passive post-abandonment maintainer of cl-emb I would say that many libraries are finished enough to use but in the ideal world could see some more development.
7:56:54
verisimilitude
Anyway, if you really wanted to protect yourself, you'd simply use IMPORT-FROM or SHADOWING-IMPORT-FROM; either of those are better than using package qualifiers constantly.
8:05:01
xificurC
(defstruct image-info name path from tag) now (apply #'make-image-info info) turns a plist into a struct. Is there something prebuilt to do the reverse?
8:06:05
verisimilitude
From memory, no, there's no default functionality for this, unless your struct is already represented as a list or vector, in which case it would be trivial to do.
8:06:59
verisimilitude
CLOS has no standard functionality for traversing all slots of an object, so no.
8:07:20
verisimilitude
YWhat you should do, xificurC, is define a macro that defines this for you, however.