freenode/#lisp - IRC Chatlog
Search
9:56:27
jmercouris
I happen to have a freind who overuses that word, so maybe I am seeing things where they are not
9:57:41
jmercouris
that is something I do wonder about, what is the purpose of defgenric when defmethod will implicitly make a defgeneric?
9:58:38
beach
There is also some default given to your &key, &rest, and &allow-other keys that might be preferable to give explicitly.
9:59:11
jmercouris
What do you mean by that last part "you get to give your preferred method combination"?
10:02:36
beach
Here: http://www.lispworks.com/documentation/HyperSpec/Body/07_ffd.htm is a list of the built-in method combinations, but you can also define your own.
10:02:38
jmercouris
so why might you want to use :method to define a method against a generic function instead of doing it in a separate form?
10:03:35
beach
If you methods are trivial, like (defgeneric consp (thing) (:method (object) nil) (:method ((object cons)) t))
10:05:58
beach
Here https://github.com/robert-strandh/Eclector/blob/master/code/reader/generic-functions.lisp are some examples.
10:07:11
jmercouris
And in that case, I might naturally ask the question, why not forgo the defgeneric altogether?
10:09:42
beach
Here: https://github.com/robert-strandh/SICL/blob/master/Code/Cleavir/Input-output/io.lisp you have an example of the APPEND method combination.
10:10:08
beach
jmercouris: Because you may want to allow for the client to override the methods, or to provide auxiliary methods.
10:10:56
beach
jmercouris: In the example, the client is T. Typically, client code will define its own CLIENT object, and then override the default method.
10:11:23
beach
Or, if they are happy with the default action, they just don't define an auxiliary method.
10:11:48
beach
jmercouris: This is the very basis of programming with generic functions, allowing client code to adapt the way the module works.
10:12:30
beach
jmercouris: I guess your experience with object-oriented programming is from a language that does not use generic functions.
10:13:39
beach
But they are probably all based on the same principles, which are different from those of CLOS.
10:14:37
jmercouris
mostly because I made too many assumptions about that snippet of code, I assumed it was internal
10:14:46
beach
In all the other languages you know, client code would make a subclass and override that way.
10:15:16
jmercouris
In this case they would just specialize on the appropriate set of classes, right?
10:15:22
beach
No, that was the very client interface of Eclector, allowing client code to customize its behavior.
10:15:37
jmercouris
so they just need to write some new defmethods with the appropriate lambda lists, and they can change the behavior
10:18:16
jmercouris
That's what I've gathered as well, and on some intellectual level, I understand some of the details, and how it works, but I haven't really internalized it, and my thinking is still shaped for a traditional model
10:18:40
jmercouris
many years of java training has done me in, but I'm slowly changing my ideas about programming, I understand the process of "de-doctrination" takes time
10:19:24
jmercouris
I know for sure other parts of my mind have changed with regards to how I think about programming as a result of lisp, but I just haven't gotten deep enough into CLOS yet, to get that same effect
10:24:02
Jach[m]
jmercouris: I've only recently cracked open "Object Oriented Programming: The CLOS Perspective" and finding it helpful (plus the hardcover has nice cover art...)
10:24:48
jmercouris
Jach[m]: I'm in the middle of gentle introduction to common lisp, maybe when I'm through with that I can take a look, thanks for the suggestion
10:35:04
jmercouris
that's why I start with a gentle introduction to common lisp, now that I've been doing lisp for a while, it sticks a little easier
10:35:34
jmercouris
PCL is indeed practical and succinct, and as a consequence, not really memorable, at least for me
10:36:32
beach
ACTION needs to remind his favorite coauthor about the many book projects we need to work on.
10:37:03
heisig
In my experience, the best way to learn and understand CLOS is to read other people's code. Some code that comes to mind is cl-dot, cl-graph, Eclector (and pretty much all of SICL), ASDF and maybe LIL.
10:37:58
heisig
But yes, the world would benefit a lot from a book on CLOS that is more practically oriented than AMOP.
10:38:35
beach
... and with better and more examples than "Object-Oriented Programming in Common Lisp" by Sonja Keene.
10:48:22
beach
I didn't like the examples. One example was about software distribution for different platforms, which doesn't speak to someone who is that new with object-oriented programming. Another example was about threads, which are not in the standard. The entire thing gave me the impression that there are few examples where object-oriented programming is useful, since it must be hard to come up with more mundane examples.
10:52:34
no-defun-allowed
Indeed it is. The rest of the book is nice but the examples (except the spam filter, that's a masterpiece) were fairly underwhelming.
10:54:55
shka_
beach: i started a blog, i will describe my last discussion with phoe regarding message/answer representation next
10:54:57
no-defun-allowed
If it were, I imagine the plet* system would do some tree generation and figure out which bindings to evaluate next while they were being evaluated.
10:57:14
no-defun-allowed
I'd just want to make the second "required" list automagically generated, which seems fairly trivial.
10:59:53
no-defun-allowed
It'd just be the variables in the value form that are in the previous bindings.
11:04:24
scymtym
finding free variable occurrences in a form generally requires code walking. if the names of the variables in questions are known (like in this case) a hack like (catch 'occurs (sb-cltl2:macroexpand-all '(macrolet ((occurs () (throw 'occurs t))) (symbol-macrolet ((VAR (occurs))) FORM))) nil) can work
11:15:34
no-defun-allowed
Code walking is very simple though. I also have a set of variables I'm only interested in too.
11:39:08
jcowan
as for predicate-based generic functions, since I am a spec writer and not (with this hat on) an implementer, I don't have to provide an efficient implementation. Lots of things in JavaScript, e.g., weren't known to be efficiently implementable when they were first specified, but nowadays fast JavaScript is a thing.
11:41:59
no-defun-allowed
scymtym: I guess it isn't as simple with macros and the like. I'd assume that the plet* forms would not cause side effects and would be "functional" to some extent.
11:42:38
ggole
Expecting something to be fast just because it would be convenient if it were fast is a good way to get a slow thing
11:46:22
scymtym
no-defun-allowed: even without macros, the analysis has to be aware of all special operators and has to keep track of lexical variables
11:55:10
pfdietz
The specified evaluation order of CL forms is a wonderful thing, compared to (say) C.
11:59:43
pfdietz
I think the poor choice was driven by how restricted C compilers were on 16 bit platforms. Tiny, tiny things they were.
12:03:57
heisig
A consequence of the unspecified evaluation order is that I consider every C and Scheme program broken unless proven otherwise.
12:04:37
heisig
I also consider every program broken that uses fixed size integers without proving rigorous upper bounds :)
12:05:38
ggole
It may have been beneficial for early compilers with weaker approaches to optimisation
12:07:39
pfdietz
jackdaniel: I can show you a perfectly correct seven line CL program that causes the SBCL compiler to blow out memory due to bignum sizes (and would not overflow if just run naively). The problem does come up!
12:07:49
heisig
jackdaniel: In this case, stopping because of heap exhaustion is the only sane option. Would you prefer your program to continue despite being broken?
12:09:40
jackdaniel
heisig: my point is that if you don't control upper bounds your program may not return correct results (because it won't return results at all!), having fixed size integers and crash on overflow is equally good/bad
12:10:37
jackdaniel
I'm of course half joking (like you did with demanding proofs of program correctness :)
12:10:52
pfdietz
In this case, it would have been possible for the program (the compiler) to succeed, just by giving up and widening the inferred types to (INTEGER * *).
12:13:06
heisig
jackdaniel: Oh, sure, if your languages crashes on overflow that is still sane (and might be preferable for real-time systems).
12:14:24
heisig
... for real-time applications. For a computer algebra system, I would be quite bothered by that.
12:16:01
pfdietz
Speaking as a compiler tester, I really like that in CL integers behave like integers. It makes it easier to write test generators. Doing the same on C was hard enough that Regehr's team got several papers out of it.
12:16:59
pfdietz
Avoiding the 100+ (?) undefined behaviors of C while generating and simplifying tests is difficult.
14:05:20
pfdietz
I vaguely recall the original C standard was influenced by the existence of the Symbolics C compiler, which if I recall correctly translated C to Common Lisp.
14:05:48
foom
no, everyone agrees that no 1s complement platforms exist anymore. The undefined-behavior is there, now, for 2 reasons:
14:06:00
semz
if it's undefined behavior, the compiler may assume it doesn't occur, which allows a few optimizations. regehr had some posts about this
14:06:01
foom
1) the compiler/runtime may detect and abort upon seeing it, instead of being required to wrap. But wrapping is almost never what users _really_ wanted.
14:08:05
pfdietz
I'm not sure detecting and aborting when going out of bounds is wanted either. Look at the first Ariane 5 (failed) launch (Ada there, not C though).
14:09:06
pfdietz
The problem was in pre-launch calibration code. It did not matter what it was computing at that point.
14:10:12
pfdietz
The code was left over from Ariane 4. But Ariane 5 leaps off the bad much faster, so a number overflowed.
14:10:42
jackdaniel
in ideal world of fixed integers (without possibility to upgrade to bignums) would be: a) signalling a condition; b) having condition handlers like in CL; c) compiler giving warnings (or errors) if there is no proper handler for the operation which may overflow - that's at least my not well thought-through opinion for this moment :)
14:13:25
semz
considering how arithmetic without error handling is impossible this seems like The Right Thing (tm), but the question is how to do it a) efficiently and b) with clean code
14:14:35
semz
(a) might be easier because the handlers will probably do some cleanup nearby, so the compiler could recognize it
14:14:38
jackdaniel
I find Common Lisp condition system one of its most amazing features (and it is fairly clean and efficient)
14:14:53
ggole
Seems the ariane 5 thing was a conversion from a double to uint16, rather than a uint16 operation overflowing
14:17:07
semz
since it's borderline impossible to write C which handles all overflow conditions and not end up with a hairball
14:22:52
jackdaniel
heisig: not so much for embedded boards like arduino, but these lose in importance every day - it becomes cheaper to standarize on arm than on atmega even for home electronics
14:23:17
ogamita
ggole: (defun speed (a dt s) (+ (* a dt) s)) (speed (the (unsigned-byte 16) 42) 3 0) #| --> 126 |# (speed (the double-float 42.0d0) 3 0) #| --> 126.0D0 |#
14:25:28
heisig
For modern systems, Common Lisp is almost always a good choice. Even for system programming. I recently played a game of Quake on an operating system written in Common Lisp :-)
14:25:46
ogamita
(declaim (optimize (space 3) (speed 3) (debug 0) (safety 0))) (defun new-speed (a dt s) (declare (type (unsigned-byte 16) a dt s)) (+ (* a dt) s)) (new-speed 42.0d0 3.0d0 0.0d0) #| --> -4210554732912278340 |# !!!
14:28:21
jdz
ogamita: you first tell SBCL to not check your values, and then you complain that it does not do what you told it to do?
14:29:08
ogamita
You choose to write programs in C and then you can't complain when your rocket explodes…
14:31:36
ogamita
Shinmera: there's still a choice by sbcl implementors to allow wrong results with safety 0…
14:31:59
ogamita
Similar to C implementors. So they indulge to the same mindset and allow it to develop with sbcl…
14:33:14
ogamita
The spec also allows array-total-size-limit to be 1024, sbcl implementors still set it to a higher value…
14:33:19
jdz
ogamita: (sb-ext:restrict-compiler-policy 'safety 1) and you will live happily ever after.
14:49:44
shelvick
Has anyone run into this problem before with ironclad or nibbles? https://pastebin.com/bTVL8FNs
14:53:45
beach
semz: I am convinced that if you just add a few primitives to your Common Lisp implementation, then it becomes a perfect fit for system programming.
14:54:39
pfdietz
shelvick: nibbles uses internal SBCL things that change frequently, so don't expect recent versions to work with old SBCLs.
14:57:45
semz
embedded and kernel stuff, primarily. though admittedly the main motivation was more of a vague "let me get rid of C and its nonsense already"
14:59:27
beach
semz: Well, clearly full Common Lisp is probably too big for many embedded applications.
15:00:24
beach
semz: I am guessing you mean applications that must manipulate arbitrary addresses in arbitrary ways. In those cases, I think system programs written in C probably rely a lot on undefined behavior.
15:02:24
beach
semz: On the other hand, if we abandoned the silly (and very old) idea that an application program should have access to the full address space (including the stack) as if it had access to a raw computer, then we could write a very safe operating system using Common Lisp. But it would not have a "kernel" in the Unix sense of the term.
19:08:35
anamorphic
Hi, Is this the most effective way to convert a sequence of any kind of numbers to a one-dimensional array of double-floats? (let ((x-array (make-array length-x :element-type 'double-float))) (map-into x-array #'(lambda (value) (coerce value 'double-float)) x-sequence) ...)?
19:25:22
aeth
anamorphic: you might want to use the type (simple-array double-float (*)) instead of (vector double-float) in case the latter doesn't make it a simple-array
19:26:12
aeth
if it's simple, that means there's no fill-pointer and it's not adjustable (and maybe a few other things) so it's faster.
19:27:48
aeth
A vector is a 1D array. A simple-vector is a simple T vector. A simple-array is a simple array. There is no specialized simple-vector. There are specialized vectors, apparently, since pfdietz just defined one. This is a flaw in the standard imo
19:28:40
aeth
9 times out of 10 your simple-array is going to be a 1D array (i.e. a vector) but you have to use the more verbose multi-dimensional array syntax to talk about it
19:29:16
aeth
Usually you get around this by defining your own easier-to-type type if your code is filled with it.
19:40:52
aeth
(If simple-vector worked like everything else you could just say (simple-vector double-float) instead of (simple-array double-float (*)) since the size would be an optional argument at the end. But you can't.)
19:47:36
anamorphic
Yeah had noticed that about simple-vector. Is it a historical thing that it doesn't have a type specializer?
19:54:06
White_Flame
but yeah, I've been bitten by that as well in utf-8 and byte buffer conversions. One library uses simple-vector, the other uses simple-array, and they are not interchangeable; you need to copy the data to an object of the other type in order to bridge them
20:08:25
oni-on-ion
https://sirherrbatka.github.io/blog/2018/10/11/cl-data-structure-ranges-are-pretty-cool/
20:27:11
XachX
the 403 in that case really means "no object is here but i don't want to tell you that"
20:27:11
shelvick
Oh? interesting... I was doing something through qlot which has worked before up until maybe an hour ago
20:27:50
XachX
shelvick: https://beta.quicklisp.org/dist/quicklisp/2018-08-31/distinfo.txt is the normal pattern
20:30:54
aeth
If you use a simple-vector for octets then everything's 4x larger in memory (if 64 bit) and the compiler loses any chance at knowing what type it is when AREFing
20:43:10
aeth
(Oh, and the GC has to iterate through the T vector to see if anything's a pointer, doesn't it?)