freenode/#lisp - IRC Chatlog
Search
10:42:28
dim
am I understanding correctly that those `out' implementations are compatible with that of the format-stinks paper?
10:44:15
_death
mcdermott wrote the format-stinks paper, and recommends it there, so I'm guessing it's compatible.. mine is inspired by his, so maybe
10:46:56
_death
for mcdermott's see src/ytools in https://sourceforge.net/p/clocc/hg/ci/default/tree/
10:58:15
splittist
format strings can be commented. That no-one does it is either a bad habit, or a sign that they're not really mysterious write-only incantations after all.
11:08:30
dim
far too easy to make mistakes, some forms are impossible to remember (0-pad a number to n digits on the left?)
11:12:10
_death
dim: I too dislike use of regular expressions.. I agree with Naggum's point of view, that it may be useful as a user-visible feature, but not really for use in programs
11:15:07
axion
pjb: Thank you for replying to peter's sbcl-help message. We have been trying to debug this for a long time, and your answer makes perfect sense, however, the solution is not going to be ideal for us, as it introduces complexity at the macro call site for the user. This macro is actually used by another macro that handles working with several vectors at once, and worse, for several 4x4 matrices.
11:16:32
_death
dim: with out you could also define your own user-op so it's (out (:u hex32 42)) or something
11:27:54
pjb
axion: well, while you have still 3 slots, your macro is ok. But once you have more, you won't have x y z parameters, but &rest values, and you will write: (map-into pv #'identity values).
11:27:59
axion
pjb: peter failed to show why these macros truly exist. In most cases, the user is supplying 3 15-length arrays
11:30:18
pjb
Now, you may want to use a compiler that unroll the loops, or use your own looping macro to unroll them.
11:30:58
axion
To be honest, we are only interested in sbcl performance, however we definitely want conformity/portability
11:32:23
axion
We went through great lengths to type-annotate and inline suitable functions, and wrote macros such as this to make writing and visualizing everything simple.
11:32:24
pjb
Unless you or the compiler can use vectorial instructions. IIRC sbcl can do some, but I don't know on what conditions. You can always implement the needed VOP.
11:33:06
pjb
So you'd write a loop using your own looping macro, but instead it would use vectorial instructions to implement the body.
11:33:43
pjb
(of course, you'd have a conforming implementation of the macro for other implementations or processors).
11:35:00
axion
pjb: Yes VOPs were something we discussed, and the sb-cga system does this already should we need it. This may be used on other implementations though, so portability is a concern.
11:37:31
Younder
Reader macros are by their nature not isolated. In particular packages can't restrict them
11:37:48
axion
pjb: I can give you an example of how this macro is used in the wild, and why it is nice
11:40:02
axion
pjb: https://github.com/mfiano/gamebox-math/blob/master/src/matrix-ops.lisp#L234 pretty much this whole file is it's main use in the form of WITH-MATRIX and WITH-MATRICES, and the macro definitions are in the matrix-base.lisp file.
11:40:25
|3b|
ACTION didn't mean 'local' though, just something like #16!m could expand to symbols M0 .. M16 in some useful form (list of symbol-macrolet definitions, input to some normal macro, etc)
11:41:46
|3b|
that way you get names defined at read time (so in correct package), but without having to type them out explicitly
11:42:11
pjb
axion: yes. You see, if I had to write this matrix-invert! function, I would NOT write it myself! I would write a macro to expand to it!
11:44:17
Younder
Matrices are tricky. Diagonal ones. Sparse ones. Trigonal ones. Lot's of efficiency issues.
11:44:49
|3b|
Younder: simpler for the ones used for 3d transforms though, small and fewer special cases to care about
11:45:01
pjb
axion: now, with-accessor defines symbol-macros that expand to the accessor call each time it's used. This may, or may not be faster than local lexical variables, when you only read the slot several times…
11:46:14
pjb
In the matrix*!, each slot is read 4 times; it could be faster to read it once, store it in a local lexical variable and then read it 4 times from there. If the processor has a lot of registers, those temp could be stored in registers.
11:47:16
axion
pjb: I see, so I'm going to have to discuss with him rewriting the macros for several reasons now.
11:47:34
|3b|
dual quaternions get you a bit better coverage, but still don't handle everything a 4x4 matrix does
11:48:10
axion
Well they do represent scale, but must be normalized and thus losing that information for certain operations
11:48:15
pjb
But for the reader macro idea, you could have something like: [o00 that would expand to (aref o 0 0)
11:48:59
axion
reader macros is actually something I never attempted with CL in my more than a decade of use. Might be fun to learn
11:50:31
|3b|
ACTION was thinking #4m(o out-matrix) that expands to (((o00 math-lib:m00) (o01 math-lib:m01)) ... out-matrix)), used as `(with-accessors ,@#4m(...) ...)
11:50:32
pjb
So you wouldn't even need to have a with-matrices macro, just name your macros with a single letter.
11:51:19
|3b|
though that ends up a bit ugly now that i type it out, probably want a normal macro in the middle to expand the lists instead of ,@ :/
11:53:26
|3b|
ACTION thinks surface syntax should be an editor feature rather than language feature anyway though :p
11:53:27
axion
Well thank you for the suggestions. I am lost when it comes to reader and compiler macros, so I'll have to do some research first.
12:18:35
Younder
Well compiler macros happen just before compilation and after macro expansion. Easy enough to grook really. Just compiler dispatch on types. Look at the source for CL-PPCR fes
12:19:38
BernhardPosselt
why do lisp dialects just keep on popping up? what does lisp do better than haskell? or is it just so simple to write a parser :)
12:20:59
beach
BernhardPosselt: This channel is about Common Lisp, so we don't care about other dialects. :)
12:21:25
easye
BernhardPosselt: It is pretty easy to make a simple Lisp. When encountering a new language, I often try such an implementation.
12:22:12
beach
BernhardPosselt: Here is alist of features of Common Lisp. You can compare it to what Haskell does: http://random-state.net/features-of-common-lisp.html
12:23:00
easye
Younder: A simple Forth is definitely easier that a simple Lisp, but making the Lisp reader for parens tells me a lot about the I/O in the new language.
12:23:09
|3b|
ACTION makes common lisp dialects for same reason, some feature i want that i can't get from the original, or thing i don't like about the original and hope i can do better
14:23:31
argoneus
is lisp/funcprog in general a bad idea for things like IRC bots or network processing stuff in general?
14:23:51
argoneus
when I think about network I think about it imperatively, and I can't really imagine how it'd work with lisp
14:27:27
argoneus
hmm, so all in all it should be pretty much the same difficulty, just a different style so to speak?
14:27:40
rumbler31
also https://github.com/phoe/secure-read exists if you want to make your protocol parseable by lisp (read
14:29:19
rumbler31
i would look at trying to write a server, if thats what you're talking about, with iolib
14:30:36
rumbler31
fair warning, if you're on windows, IOlib might need some work on your part to get built. maybe
14:31:11
beach
argoneus: Common Lisp (the language to which this channel is dedicated) is not particularly "functional" in that sense of the word.
14:31:46
rumbler31
I used (read to prototype a text protocol between two applications. I couldn't be bothered to parse the format they wanted yet, so I made it (read-able and then sat on a telnet session and typed/pasted the data in
14:32:42
beach
argoneus: The absolute "coolest" thing about Common Lisp is not that it allows functional programming. Instead it is its object system, CLOS.
14:32:42
argoneus
I was actually thinking of using Clojure or such, thought this channel was for general lisp dialect discussion
14:38:29
axion
What is more troubling is legal but dangerous code. I believe beach wrote a paper on a sandboxing proposition years ago I helped proof-read. I wonder what the status of the ideas present are these days.
14:46:17
phoe
axion: AFAIK my library returns two values, with the other value being an error code if a reader error happened.
16:05:00
sebboh
aeth, pjb, didi, continuing yesterday's conversation... trivial-shell:shell-command returns multiple values, two of which are ... streams, or large strings, or something. (stdout and stderr) I think they are actually strings. You said something about registers. What is a register in this context? Are we talking about a piece of the "vm" or "intepreter" here? Is it appropriate to store a string of unknown length (unix command
17:47:09
didi
Can I expand stuff like #'fn to inspect what it turns out? Like I can use C-c C-m in SLIME to macroexpand a macro.
20:38:31
pjb
sebboh: when the data cannot fit a register, the register contains a pointer to the data instead. It's still good to have the pointer directly accessible in the register, instead of having to read it from memory.
20:42:50
aeth
Does anyone know what the maximum efficient number of values in (values ...) is on typical modern implementations? multiple-values-limit is "not smaller than 20" and in 64-bit SBCL is 4611686018427387903, but I doubt it's as efficient with 4611686018427387903 as it is with 4.
20:44:12
easye
aeth: I think it is mostly about efficiency of space, not time (other than the time it takes to construct a gadzillion VALUES to return in the first place)
20:45:55
jackdaniel
if it's small number (say - 2), it might be quite beneficial to store it in registers if you have control over them
20:47:03
aeth
Well, I'll be specific. With 3 or 4 values, it's (usually?) better just to work with values directly than to create a temporary array to represent a 3D vector or a quaternion. What about e.g. the 16 values of a 4x4 matrix?
20:47:50
aeth
There has to be some point, especially in SBCL's 4611686018427387903, where an array (not a list!) beats multiple values, right?
20:48:46
aeth
The alternative here would be an array declared dynamic extent, which at least for size 4 produces different (larger) disassembly than values
20:49:22
jackdaniel
aeth: do you have actual application where you have to optimize such case, or it's just what-if in a vain?
20:49:46
jackdaniel
because unless it's indeed a bottleneck I'd say - choose whatever fits your semantics best
20:50:00
aeth
jackdaniel: Yes, I'm writing a 3D game engine. There are lots of temporary vectors and quaternions.
20:50:45
aeth
It is at least looking like multiple values for sizes 3 and 4 beat specialized arrays of sizes 3 and 4 declared dynamic-extent.
20:52:17
aeth
jackdaniel: #lispgames is more about higher level game design than the finer details of Common Lisp performance.
20:52:39
aeth
And I suspect what most people know about CL performance in #lispgames is for SBCL and maybe CCL or ECL, not modern implementations in general.
20:53:14
aeth
I have been optimizing SBCL and CCL, halved their CPU usage, now they're mostly < 3% CPU, but I can't get 60 FPS in ECL for some reason.
20:54:01
aeth
I only use objects before the game loop (rather than during), and for the game window object.
20:54:49
jackdaniel
either way many people there know a lot about optimizations, they do write 3d engines after all
20:55:24
aeth
I have exactly one method remaining in my code, apparently. It is run before the game loop.
20:55:59
aeth
I do use type declarations extensively. Could that hurt performance in ECL even though it helps it in SBCL and CCL?
20:57:08
aeth
jackdaniel: I mostly profile in SBCL because it's so much easier to profile with. I can't even use disassemble in ECL, apparently.
20:57:33
aeth
It's possible that there's a bug in cl-opengl or cl-sdl2 that hurts performance only in ECL.
20:59:44
jackdaniel
either way I don't think your bottleneck lies in returning multiple values from function
21:00:55
aeth
Well, I have eliminated almost all consing in SBCL (it's easier to do it there than in the others... I'll attempt CCL at some point)
21:22:34
Bike
but yeah, for (sb-profile:profile ..names...) ...whatever... (sb-profile:report) you just do (with-monitoring (...names...) ...whatever...) i think.
21:32:21
aeth
It takes 0.025519 seconds per call in ECL and (/ 60f0) => 0.016666668... so that right there is going to blow the 1/60 of a second budget
21:33:48
TeMPOraL
jackdaniel: oh, so you updated a portable profiler; should have googled harder before writing my own for the game engine... xD
21:34:18
aeth
It's 0.000084 in CCL and 0.000061 in SBCL, so i's several orders of magnitude slower in ECL.
21:37:28
TeMPOraL
ACTION is reminded of that time on VM where ~90% of my game time was spent on ioctl...
21:39:06
aeth
Oh, I forgot, I no longer inline draw, so I can profile the per-entity draw function instead of the iterate-over-every-entity render function.
21:39:56
aeth
It doesn't help that ECL apparently doesn't measure consing. I know it's lying when it says 0 consing in monitor:report-monitoring, because two functions I was checking definitely still do some consing, including the render one
21:40:54
Bike
assuming you got the new metering, it should work, especially since jackdaniel also maintains ecl
21:41:17
aeth
It looks like each draw call takes 0.002299 seconds, or about 14% of the time I have to do literally everything.
21:42:27
TeMPOraL
gonna take a wild guess here; my problem was caused by glGetError being expensive; maybe try recompiling cl-opengl with #+cl-opengl-no-check-error ;)
21:43:18
aeth
I've optimized far more than I probably should at this point, in part because ECL can't hit 60 FPS