freenode/#lisp - IRC Chatlog
Search
17:19:54
Beep-Lord
LdBeth, doesn't org-mode have a way to export to LaTeX? You could probably examine some of its exported code to see what it does with inline code.
17:49:42
makomo
Ukari: if you want to specialize on nil you can use EQL specializers: (defmethod test ((x (eql nil))))
17:52:13
Ukari
makomo, is it possible to write like this ? (defmethod test ((x (or null function))) (print "null or fun"))
17:53:18
makomo
Ukari: nope. a specializer can either by a CLOS class name or the special EQL specializer of the form (eql <something>) where <something> will be evaluated when the method is defined
18:00:12
pjb
Ukari: (defun test/null-or-function (x) (print "null or fun")) (defgeneric test (x) (:method ((x null)) (test/null-or-function x)) (:method ((x function)) (test/null-or-function x)))
18:03:43
makomo
Ukari: it's not that it doesn't support multiple arguments, it just doesn't support multiple *specializers*
18:05:49
pjb
(or x y) is a TYPE designer. There is no such thing for classes, (but perhaps, mixing subclasses: (defclass foo (a b) ()) but 1- it's not possible with built-in classes, 2- it's more like a AND than an OR.
18:08:34
Ukari
which is recommand to use when have multiple types? single defgeneric or multi defmethod?
18:09:19
makomo
Ukari: you need both a defgeneric and a defmethod. the example that pjb wrote showed an "inline" definition of a method using the :method option with defgeneric
18:09:23
pjb
If you have multiple types, you have to use TYPECASE (or CTYPECASE or ETYPECASE) explicitely.
18:11:23
Ukari
i found that it also supports struct and null in defmethod, are null and struct both a kind of classcase?
18:11:29
pjb
Class types are just a gateway between CLOS and CL minus CLOS, so that you can use TYPECASE with CLOS instances. But they're not useful otherwise. If you have classes, then just consider classes and do OOP. If you have types, then do usual procedural programming using typecase.
18:17:18
makomo
i'm not 100% sure how accessor (:writer, :reader, :accessor) properties are inherited
18:17:33
pjb
Ukari: but be careful when reading clhs, because the information is spread all over the place. For example, clhs defstruct says "defstruct defines a structured type, named structure-type, with named slots as specified by the slot-options." but in the description of the :type option, it also says: "defstruct without a :type option defines a class with the structure name as its name. The metaclass of structure instances is
18:18:18
pjb
Ukari: this means that not all "structures" are classes. (defstruct point x y) -> defines a type and defines a structure class. (defstruct (point :type vector) x y) -> only defines a type!
18:19:20
pjb
Ukari: this is why if you just say that you have a structure, and moreover, if you say that you have a structure TYPE, then you CANNOT use defgeneric/defmethod because you've not affirmed you had a structure CLASS!
18:20:08
pjb
ebrasca: you can definitely add accessors to slots. And also change the type (as long as you respect the Lyskov substitution principle).
18:22:07
pjb
ebrasca: everywhere you have an instance of a class, you must be able to substitute an instance of a subclass and it should still work.
18:23:02
makomo
ebrasca: but why exactly would you want a different accessor for the same slot? what's the rationale?
18:23:05
pjb
ebrasca: this means that if you change the type of a slot in a subclass, you must still be able to to store the all the values of the type defined for the slot in the superclass, and the reader should not return any value outside of that type.
18:23:49
pjb
This is why it is in your best interest to NOT specify any type to the slots of your superclasses or pre/post condition to methods of your superclasses!
18:24:56
ebrasca
makomo: ext2 https://wiki.osdev.org/Ext2#Superblock , ext4 https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout#The_Super_Block
18:25:28
makomo
ebrasca: you'll have to explain that to me in the context of your CLOS model. i can't really go and read that
18:25:47
pjb
(On the other hand, if you specify types and pre/post conditions in the superclasses, and respect them in your subclasses, you benefit greatly from OOP; few people understand it, and end rejecting OOP entirely, because they've spend all their time kludging and hacking around this).
18:26:53
pjb
sometimes you need to enforce additionnal or different constraints, (but for additionnal constraints, you should just override the usual accessors).
18:27:22
pjb
But it's right that it may be a hint that you're doing something very wrong: using subclassing for implementation, instead of structurally!
18:28:30
pjb
ebrasca: don't look at what C coders wrote! They do horrible things, like reusing memory for different purposes, etc.
18:29:12
makomo
what pjb said ^. it doesn't necessarrily follow that the best model is ext2 <- ext3 <- ext4
18:30:03
pjb
Well, you can mount an ext3 device as an ext2, IIRC. The journal is stored separately, and it will be rebuild when you remount it as ext3.
19:33:28
Ukari
(defun test (&optional x)), how could i know the difference between (test) and (test nil) ?
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.