freenode/#lisp - IRC Chatlog
Search
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?)
22:16:51
White_Flame
oh, regarding the above discussion, the binary type mismatch was simple-array of bytes, vs vector of bytes
22:17:24
White_Flame
sb-ext:octets-to-string for example requires a specialized (vector (unsigned-byte 8))