freenode/#lisp - IRC Chatlog
Search
22:29:28
k-hos
does common lisp or sbcl in particular make any guarantees about bit size for integers?
22:31:15
aeth
ub32 may or may not work. It will almost certainly work in 64-bit Lisps, and might work in 32-bit Lisps, if you work around some limitations.
22:31:38
aeth
And, yes, you can also set arbitrary ranges with (integer 0 1) (integer 3) (mod 360) etc.
22:33:07
aeth
The primary advantage of rounding to something like (unsigned-byte 32) is that it will (probably) be supported in specialized arrays (everything except bit and character are implementation-specific, but single-float, double-float and (unsigned-byte 8) are nearly universally supported)
22:34:26
aeth
they're simple-arrays that can only hold one type, which has potential advantages in allocating the array, and it tells the implementation that if you access an element it has to be of that type (so it helps type inference)
22:35:32
aeth
e.g. (make-array 3 :element-type '(unsigned-byte 32) :initial-element 0) or (make-array 3 :element-type 'single-float :initial-element 0f0)
22:36:10
earl-ducaine
k-hos: To some extent it depends on what you mean by 'bit size' Do you mean the underlying representation or do you how a CL integer is seen by other non-cl components, e.g. when exported through cffi.
22:37:09
aeth
The underlying representation when a fixnum is *probably* a signed byte with one or more leading bits reserved (SBCL reserves one, so fixnum is (signed-byte 63))
22:37:16
earl-ducaine
In particular cffi provide a portability layer for exporting CL data in exactly the format you want, including integer representation.
22:41:26
aeth
But it probably won't be efficient unless the compiler knows it's a fixnum (it could still be efficient if it's slightly larger than a fixnum in some restricted circumstances, though)
22:47:03
earl-ducaine
k-hos: CL's primary mechanism for making numerical computations fast is through the declare mechanism. The way that that works was somewhat counter intuative for me....
22:47:12
aeth
And it's nice to be aware of some potentially easy optimizations (although with integers it is often tricky to keep them fixnum)
22:48:04
earl-ducaine
Basically CL doesn't make the promises, the programmer does. In particular to keep integers within a certain range.
22:48:40
earl-ducaine
By making that declaration, the compiler is then, theoretically free, to make certain optimizations based on that.
22:48:53
aeth
Imo sometimes hard premature optimizations are actually the right thing to do, like in game engine architectures where rewriting things will require rewriting half (or more!) of the engine if you suddenly need to do it in a fast(ish) way later on.
22:49:51
aeth
Usually that can be avoided by modularizing things heavily. It doesn't take a lot of work to optimize later if you can do that. Unfortunately, it doesn't always seem to work with a game engine.
22:51:24
aeth
Imo, the core of your game engine runtime probably needs to be 'prematurely optimized' or it will never be optimized because rewriting it means essentially rewriting the entire game engine runtime. This is a very special case, though. Usually, ignoring optimizations early on is the right thing.
22:52:04
aeth
(Feel free to be as lazy a programmer as possible outside of your game loop as long as you keep it modular so tiny components can be rewritten if needed.)
22:54:13
White_Flame
modularization can slow down you runtime, too, if things can be done faster by the code doing more at once, instead of keeping functionality separate
22:54:36
White_Flame
however, with CL you can mash code at compile-time to interact how you want, if you want to put the work in
22:54:46
aeth
White_Flame: That's one of the problems with trying to engineer a game loop. The modules will probably need to be rewritten when it's time to optimize even if you did separate things into nice, clean modules.
22:55:30
aeth
White_Flame: I do agree, though. Try to do as much outside of the game loop as possible, and ideally as much at compile time as possible.
22:56:06
aeth
My latest approach is essentially: The game loop is going to be a coupled mess that needs to be prematurely optimized... so try to contain that and do as much outside of it as possible.
23:15:35
stacksmith
Is there a format directive that prints keywords with a colon, but does not quote strings?
0:20:16
borei
can somebody point to the direction where can i find documentation for the following packages, all are prefixed with sb-
0:22:25
Bike
sb-c is compiler, sb-vm is machine-specific stuff, and sb-ext is extensions provided for you to use (ok, that's not internal, but it's sbcl specific)
0:44:25
pillton
borei: Paul Khuong has some interesting articles on SBCL internals. e.g. https://www.pvk.ca/Blog/2014/08/16/how-to-define-new-intrinsics-in-sbcl/
0:44:46
pillton
borei: Or https://www.pvk.ca/Blog/2014/03/15/sbcl-the-ultimate-assembly-code-breadboard/
3:07:06
borei
pillton: yeap - im using that articles, but looking for material with wider coverage and more systematical.
7:15:01
phoe
I just committed a very short summary of the condition system over at https://www.reddit.com/r/lisp/comments/7xg61l/can_anyone_explain_conditions_to_me/du82y9p/ - I'd like a review of that comment in case I'm speaking garbage somewhere.
7:18:42
jackdaniel
phoe: handler-case unwinds the stack, so claim "Every condition handler is a function, and that function is executed right where the condition was signaled." is bogus
7:19:24
phoe
"That function may decide to unwind the stack which allows for behaviour like C++ exceptions (see HANDLER-CASE)"
7:20:02
jackdaniel
condition handlers *are not always* executed right where the condition was signalled
7:20:38
beach
I think technically it is the function that gets called, and that function may do a non-local exit.
7:21:16
beach
But, phoe also says that execution may continue after a call to a signaling function. I don't think that is the case for ERROR.
7:21:58
phoe
jackdaniel: HANDLER-CASE establishes two functions - a very short handler that just calls THROW #:G123 and performs a non-local exit, and a matching CATCH that contains the main body of the function.
7:22:07
jackdaniel
beach: in case of handler-bind function is called without unwinding the stack (so you can examine it) and in case of handler-case first stack is unwound and then function is called (that's why the first sentence is erronous)
7:22:26
phoe
but that body of the function is *not* a handler itself in the strict meaning - it is not the function that gets dynamically bound.
7:22:38
beach
phoe: That's is kind of misleading in the context though. You give the impression that in (progn (error ...) (fn ...)), FN can actually be called.
7:24:56
phoe
beach: I'm sure that with handler-bind the stack is not unwound and with handler-case the first thing that happens is unwinding of the stack.
7:24:58
jackdaniel
beach: yes, we had to switch to handler-case* in some project to be able to print backtrace of error (not of the handler)
7:25:37
jackdaniel
and handler-case* was a disguised handler-bind which did non-local exit from body
7:26:31
phoe
"Every condition handler is a function, and that function may be executed right where the condition was signaled or it may may decide to unwind the stack."
7:26:55
beach
I am looking at the expansion of handler-case in SBCL, and it looks to me like the handler function is called when the stack is still not unwound.
7:30:49
phoe
The actual handlers in HANDLER-BIND only perform non-local exit to the forms that contain the actual handler bodies.
7:32:14
phoe
Handler as in the function that gets bound by HANDLER-BIND or handler as in the function that actually executes the body.
7:32:50
jackdaniel
most intuitive (for a programmer and from the abstraction perspective) is the function which handles the condition (that is - function written by the programmar who is responsible for higher-level logic)
7:33:23
beach
jackdaniel: But in the case of HANDLER-CASE the programmer does not write any function.
7:34:44
jackdaniel
"Each error-clause specifies how to handle a condition matching the indicated typespec." ← specification how to handle a condition is arguably a handler, and the way it is invoked is implementation detail
7:36:12
jackdaniel
http://hellsgate.pl/files/c4b578f0 regarding backtraces, this snippet illustrates the practical difference ←
7:39:38
phoe
I assume that it first executes the forms it is given and only *afterwards* performs a non-local exit. Which is useful.
7:39:59
jackdaniel
beach: spec also agrees with you "(so that the handlers established around the expression are no longer active)"
7:41:36
jackdaniel
but implementation is not super-compilcated. It looks exactly like handler-case*, but it does evaluate the expression before stack is unwound
7:44:43
jackdaniel
[yet I still think, that saying that handler is invoked before unwinding a stack, while technically in-par with spec is confusing, because expression is what the programmer cares about]
7:45:01
phoe
Because I see that it's correct to name the handler as the part that is bound to the condition but it's useful to name the handler as the "useful" part that calls the forms.
8:18:18
flip214
Hmm, the CDRs on cdr.eurolisp.org/final.html have vanished - this is only a 404 now. Does somebody know the new location?
9:51:01
beach
Hmm, indentation is made much more complicated because of the presence of comments and other elements that are part of the text, but not part of the expression being read.
9:55:17
beach
ACTION instantly regrets suggesting that example; fearing that it will now be debated.
9:56:08
Shinmera
jackdaniel: Not if you expect the indentation to be as much as the comment (like I, and probably beach, do)
10:06:02
beach
And there is of course my favorite example where Emacs indents a LET binding as if it were a form.