freenode/#lisp - IRC Chatlog
Search
4:45:53
aeth
I really like the CL concept of accessors. Compared across languages, even. e.g. https://en.wikipedia.org/wiki/Mutator_method
4:51:24
Zhivago
Alternately you can see it as other languages preferring not to pollute their function namespace.
4:52:46
Zhivago
Of course, then you need some boiler plate to make something like foo_b(a) = c work, or you need another explicit function. like foo_b_set(a, b).
4:58:49
Zhivago
Yeah, something you could pass around. You can always wrap a use of a place in a lambda, but then you need one for each kind of use.
5:00:14
Zhivago
Although I guess you could do that and then use that object as a place which forwarded.
5:01:14
aeth
whoman: (defun lists-have-accessors-too (list) (flet ((caddddr (x) (cadddr (cdr x)))) (with-accessors ((first car) (second cadr) (third caddr) (fourth cadddr) (fifth caddddr)) list (values first second third fourth fifth))))
5:01:48
Zhivago
Devon: Yeah, I'm not sure why they went out of fashion -- but I suspect it's because they didn't support place semantics.
5:06:54
aeth
Zhivago: You indirectly raise a good question. Does the spec allow implementing everything (including hash tables) as lists? (Not like anyone should try to do this, though!)
5:09:02
aeth
Zhivago: or just make the car a symbol that means that it's a hash-table. Any list without a type symbol in the car is a regular list
5:14:48
Zhivago
Sometimes I wonder if starting with dictionaries and then adding schema to them would have produced a better outcome.
5:23:06
Zhivago
They're probably just one of those things that sounds like a good idea until you really think about it.
6:14:05
pfdietz
One can defined a pseudo-pointer class in CL. It would hold reader and writer functions for some actual place. Define DEREF and (SETF DEREF) methods for it.
6:16:14
dmiles
"class-of or type-of would not produce the expected results." I am litterally stuffing classof and typeof ijn the objects properties
6:20:50
dmiles
(get-opv a-similar-point) ==> ((typeof . POINT)(classof . claz_u_point)(ref . #<claz_u_point 5>)(sname . "znst_5")(instance . claz_u_point)(x . 3)(y . -4)(z . 12) )
6:22:16
dmiles
(get-opv 'sym) ==> ((classof . claz_symbol)(name . "SYM")(PACKAGE . #<PACKAGE COMMON-LISP-USER>)(typeof . SYMBOL) )
6:25:12
Zhivago
The point being that if you re-use something but have class-of report something else, then it no-longer has the semantics of what you were re-using.
6:25:47
dmiles
well i wanted to proably switch out the underlying structure as i get more experience
6:26:40
dmiles
i started out using asserted relations (typically that is the fastest) ... but it was messing with my setcdrs
6:28:11
dmiles
now i on first setf move the property onto the dictionary .. so symbol-plist and values are on the dictionary
6:30:22
dmiles
(i just mentioning it because i wonder if i'd be happy ever putitng oeverthing on one datastructure)
6:32:25
dmiles
oh where i was going is that i have sometimes a tree of storage pacakge[string]->symbol->value->classof
6:38:07
dmiles
some props i jsut synthesize there: https://github.com/TeamSPoon/wam_common_lisp/blob/master/prolog/wam_cl/soops.pl#L372-L394
6:40:22
dmiles
the language does at least come with a locative :P https://github.com/TeamSPoon/wam_common_lisp/blob/master/prolog/wam_cl/typeof.pl#L21
7:00:35
dmiles
has anyone done a setf expander that is based solely on gettign first class locatives?
7:02:40
dmiles
i am temped to continue doing it traditionally first with (get-setf-expander ..) returning a function call.. but would be nice so see something else
7:05:02
dmiles
in prolog a variable, is insufficent was a locative i have to use '$LOC'(TermPtr,Offset) % a bit like C.. but at leas the GC moves my pointers
7:07:59
dmiles
so it looks like: TermPtr = cons(a,b), L = $LOC'(TermPtr,2), set_locative(L,b2), to 'replcd
7:19:12
beach
jackdaniel: He is making statements about your ancestors and your dexterity, as compared to his own.
7:22:24
dmiles
There is a very strong genetic line that has moved in and accrossed europe over the centuries.. many of the people ended up in russia (my fammily did)
7:23:14
dmiles
The head of Cycorp and many many programmers that have been hired at cycorp have ended up comming from this genetic line
7:24:45
dmiles
most of us are either left handed or close to it.. actually a few yearts ago at a dinner 25 out of 28 of us relize we are all left handed
7:27:03
dmiles
yeah.. i was trying to confirm it was "a thing" i could point jackdaniel's to and ran acrossed the high mobidity rate :(
7:44:16
jackdaniel
Xach: regarding top 100 downloaded projects in Quicklisp: you count raw downloads, or things which are quickloaded? For instance if I type (ql:quickload 'foo) and foo depends on alexandria (so both are downloaded) – is the counter increased for both foo and alexandria?
7:52:40
aeth
This... is incredible really. I can copy the basic concept of with-accessors (let above a symbol-macrolet above the body) and abstract everything, with the only issue being that M-. doesn't like it, i.e. M-. looks for the definition of the symbol and fails to find it because the symbol is just a shorthand for some accessor-like form.
8:22:10
aeth
All that's left to settle is how many ;s to put at a comment that serves as a section title within a long file.
8:25:17
whoman
i have a feeling that some people have gone crazy or are going crazy with lisp. shoehorning it into how they are thinking, rather than kind of meeting half way. there is a secret whispering in the clay to be sculpted into this or that shape ... just got to listen... and get a decent keyboard.. =)
8:26:37
whoman
i wonder how the Matrix would benefit from our human intervention of giving values to numbers. especially them pretty pesky pickly adjectivies
8:28:43
whoman
if we cannot work out our problems linguistically aka symbolically, i strongly feel certainly confident that surely we are getting too deep into the self-projected communal holograms
8:30:44
whoman
lists/trees of words/symbols, which mean different at different times and contexts; eval, compile, read, write, etc... this lisp thing should be rationed to the common folk. digital acid over here
8:33:39
whoman
people be getting all stuck up in that there them ideas and ideals of real words meaning real things. its good to experiment. programmers are magicians =) the current alchemy is to.. something human something computer something earth something science... well breaking habits. we should give ourselves more credit - look at all of this stuff we made !! holy hell what potential is life! ahem i hope everyone is inspired to their magnum opus
8:39:35
shrdlu68
Hello, is anyone aware of a library that has functionality for generating combinations with repitions?
8:53:59
mrSpec
shrdlu68: I don't. But you know that you can use remove-duplicates with :test #'set-equal? ;)
8:54:37
alandipert
does anyone have ideas about how i could further speed the ev2! function? https://github.com/alandipert/advent-of-code-2017/blob/master/day05.lisp
8:55:54
alandipert
i tried inlining it in the run function, but that didn't seem to make any difference, so stuck with funcall
8:58:35
hajovonta
mrSpec: that would not remove one of '(a b) and '(b a) because these are not identical.
9:01:40
aeth
alandipert: That's because input is a global variable, and those are going to be slow because they're not lexical (or at least, the portable ones aren't)
9:02:48
hajovonta
XachX: even with custom test function, it's probably better to come up with a smart generation algorithm from a performance viewpoint
9:03:35
aeth
alandipert: why so many copies? You copy it twice, once when you convert it into a vector and then again with copy-seq
9:04:50
alandipert
aeth because ev2! mutates it.. i'm not sure the copies dominate since they're not in the hot loop (lines 36-37)
9:10:32
aeth
also, if you're sure they're always fixnum, try benchmarking with '(simple-array fixnum (*)) instead of 'simple-vector
9:11:08
alandipert
aeth the input is user-dependent, but mine is here if you want to try it: https://gist.github.com/alandipert/63e4502350d90d7b251e99cac40a3895
9:14:54
alandipert
the time to beat is 130 ms.. that's how fast a similar and type-hinted clojure algorithm does it on my machine. currently my lisp goes to ~230ms
9:18:52
beach
alandipert: Do you have to use simple vectors? It might be more efficient to use specialized vectors.
9:19:45
aeth
If you want to make a higher-order-function faster, you can usually do that by converting it into a macro, afaik.
9:20:03
alandipert
beach i don't think they have to be simple, i'm ignorant of this swath of CL :-) i went with simple because it seemed like.. the simplest
9:21:10
beach
alandipert: Well, in Common Lisp a simple vector has element type T. It might be better to use a vector type that stores numbers.
9:21:12
aeth
All I did was replaced the funcall with (progn ,@body) and now I define a function instead of passing in a higher order function. Real code should also use gensyms in macros.
9:23:22
aeth
Giving it a fixnum type doesn't make a big performance difference because fixnums are already unboxed (unlike e.g. double-float), fixnums will fit in a vector already, and it's being told they're fixnums with (the fixnum ...)
9:24:08
aeth
Even if it made no difference, though, '(simple-array fixnum (*)) in your coerce and removing the (the fixnum ...) feels more idiomatic
9:30:56
aeth
alandipert: Make sure that the length is known. That's the big thing for vectors. e.g. (declare (optimize (speed 3)) ((simple-array fixnum (1000)) code)) And use a macro instead of a higher order function, i.e. put the loop in a macro, and make the part that differs the body.
9:34:58
alandipert
aeth i can see how inlining via macro is faster, i was kind of hoping there would be a way to parameterize via defun name at least. and use (declare (inline ...))
9:35:25
alandipert
aeth https://gist.github.com/alandipert/a15a83cb49d9cabf95781b7d987bbcab is my attempt at that, no faster though
9:35:44
aeth
SBCL doesn't trust you, btw. It doesn't believe that it's not a fixnum because you're doing addition, afaik. When I disassemble, I see three object-not-fixnum-errors. If the numbers have a tighter bound than fixnum, you can save some checks each iteration of the loop (or at least, some of them might be in the loop)
9:38:45
aeth
i.e. instead of calling a function, you're inlining the whole thing into the loop iteration manually, with the macro.
9:40:00
aeth
SBCL cheats with its built-in higher order functions, and even then the cheating is a leaky abstraction and you can easily ruin performance.
9:44:58
alandipert
jdz its this clojure code, on java 9/macos, on i7 skylake https://github.com/bhauman/advent-of-clojure-2016/blob/master/src/advent_of_clojure_2017/day05.clj#L50-L59
9:52:17
aeth
And afaik you can meet the desired performance if you replace (evfun code ptr) with (progn ,@body) and redefine the functions to use this macro instead of to be passed in. Additionally, declaring it as a (simple-array fixnum (1000)) instead of * (unless it's going to be of a variable size)
9:54:05
aeth
You get a big, scary "SB-KERNEL:HAIRY-DATA-VECTOR-SET/CHECK-BOUNDS" in the disassembly without a known length, and it's every iteration of the loop because it's in ev2!
9:56:05
alandipert
jdz cool, i'll give that a look later. off to bed for now, thanks all for the help!
9:56:23
aeth
schweers: calling that function to check bounds 2000 times might have an impact in the performance if you're trying to minimize it
9:57:00
aeth
A lot of the time, it's not important. This is something that's trying to be made as fast as possible afaik.
9:59:29
aeth
Found the source: https://github.com/sbcl/sbcl/blob/7aa16ffc71fb5c04458297978292daa7f3f37dac/src/code/array.lisp
10:06:05
aeth
jdz's version gives me a consistent 0.69, which is twice as fast as the macro-ified version of ev2+run. Giving it a known length of 1000 speeds it up to about 0.64. More than I thought, but fairly insignificant. It gets rid of several bounds checks, but the bounds checks probably aren't being called every iteration anymore.
10:06:58
aeth
The macro version probably gave such a dramatic improvement because the compiler didn't have to bounds check as often.
10:09:22
aeth
known size is 2 bounds checks and 3 fixnum checks; unknown size adds 2 bounds checks; safety probably removes all the checks because the algorithm is flawless
10:12:34
alandipert
jdz your code is awesome, thanks for sharing. i like not using fancy loop stuff. ok now to bed for real :-)
10:12:36
aeth
You might be able to remove some more checks if you're clever, without resorting to safety 0. That can get you some of the way there.
10:13:37
aeth
e.g. maybe they're 32 bit signed integers? Then maybe the compiler can assume fixnum longer.
10:15:39
schweers
aeth: your measurements pretty much confirm what I suspected: bounds checks are not that expensive, since running times of programs on modern hardware are pretty much limited by the speed of memory operations.
10:19:57
aeth
Individually, the checks are pretty cheap. Collectively, they apparently add up. I don't get half the time, though. I get 0.04 seconds in the safety 0 version. And half the checks that are being removed are checks for fixnum.
10:20:57
schweers
you can go from 0.69s to 0.04s? not bad, that on the other hand is not what I expected
10:22:29
aeth
Also, that's why you should always get in the habit of putting the leading zero! 00.64 would have been obvious
10:25:50
aeth
Here's the overhead, btw: (let ((foo #(0 1 2 3 4 5 6 7))) (time (dotimes (i 10000000000) (sb-kernel:hairy-data-vector-set/check-bounds foo 4 42))))
10:29:04
aeth
Or if that's not good enough: (let ((foo (coerce (loop for i from 0 to 10000 collect i) 'simple-vector))) (time (dotimes (i 10000000000) (sb-kernel:hairy-data-vector-set/check-bounds foo 400 42))))
10:30:34
aeth
In order for it to matter, your data has to be huge or you have to have a very strict time constraint (maybe 200 frames per second?)
11:15:23
shrdlu68
When working with arrays of integers less than 128, is there a performance benefit in using :element-type '(unsigned-byte 7) rather than '(unsigned-byte 8) ?
11:17:42
schweers
according to the CMUCL manual there are (or were?) even implementations which used even worse representations in such cases
11:20:14
jmercouris
I have the following code https://gist.github.com/78247fc1030e208f023c50323d46b3e8
11:20:59
jmercouris
Additionally, the contents of "help-contents" is not actually being used within ps:ps somehow
11:23:49
schweers
if it’s a macro, and doesn’t use its argument ... on the other hand the SETF expression does use it anyway. I’m also confused
11:26:37
mercourisj
sorry, my internet keeps cutting out, I am checking the logs though, so don't worry
11:27:03
mercourisj
from the project description: "The ps macro takes Parenscript code in the form of lists (Parenscript code and Common Lisp code share the same representation), translates as much as it can into constant JavaScript strings at macro-expansion time, and expands into a form that will evaluate to a string containing JavaScript code."
11:31:34
jmercouris
Whereas it should look like "document.body.innerHTML = "contents of help-contents variable";"
11:36:04
schweers
shrdlu68: As far as I know this cannot be done. I wish there was a way though. Or rather I wish this could happen automatically.
11:37:15
schweers
jmercouris: can you verify that SETF has any effect? Also, have you tried factoring the (PS:PS ...) expression into a function and calling that with HELP-CONTENTS as an argument?
11:38:46
jmercouris
schweers: I haven't tried that, but I don't see how that would help, I didn't write ps:ps it is part of parenscript
11:39:40
schweers
I know, but I don’t know anything about parenscript, so I have no idea what the macro actually does.
11:39:42
mercourisj
schweers: setf most definitely has an effect, if you look at the outputted html it has an assignment on the innerhtml of the body
11:43:44
jmercouris
schweers: Correct, it must be in JS the point is to set the text of the web page
11:44:18
jmercouris
schweers: Correct, it must be in JS the point is to set the text of the web page
11:50:54
mercourisj
If you look in the reference here:https://common-lisp.net/project/parenscript/reference.html
11:51:14
mercourisj
You'll see the section "Symbol Conversion" which is what is happening with the value of help-contents, rather than an eval to its value
11:54:09
jmercouris
alright, so reading the manual again, I retried ps:lisp, apparently ONLY at runtime does the lisp form get evaluated, so I was doing the macro expansion and it looked wrong to me, but did actually work
11:54:41
jmercouris
so to anyone reading the log in the future, the following is how I solved my problem (ps:lisp help-contents) instead of just using help-contents which was being translated to a js symbol helpContents
12:02:16
Bike
if you know it's an (unsigned-byte 7) you might as well tell the implementation so, since it upgrades regardless
12:03:12
Devon
(ps:lisp '(upgraded-array-element-type '(unsigned-byte 7))) => (UPGRADED-ARRAY-ELEMENT-TYPE '(UNSIGNED-BYTE 7))
12:05:40
jdz
I wrote a bit about arrays ages ago here: http://t-b-o-g.blogspot.com/2009/10/brians-brain-on-common-lisp-take-2.html </shameless-plug>
12:23:13
schweers
jdz: but does it have any benefit declaring the element type as (unsigned-byte 7)?
12:23:47
schweers
now that I think of it: there may be cases in which the compiler can prove that an operation on an element will not be larger than (unsigned-byte 8)
12:27:56
schweers
but I may very well be wrong about that, I’m not old enough to remember a time when a byte wasn’t 8 bits
12:29:02
jdz
I remember at least some architectures from early lisp days had 36-bit words, which I think implied 9-bit bytes.
12:35:19
jdz
I also remember reading about strings being chunks of 5? characters (each one 7-bits) packed in words?
12:41:57
jdz
Oh, this might be it (from IBM_704 page): «Alphanumeric characters were usually 6-bit BCD, packed six to a word.»
12:45:56
Devon
PDP-10 SIXBIT for filenames, SQUOZE for symbol tables, 7-bit ASCII for text, 8-bit SAIL for terminal output, 9-bit... not sure but I'm sure it got some use.
13:19:33
pjb
Well, foremost, the character set was determined by the printer chains. They could easily be changed for each printing job!
14:54:35
tfb
jdz: Symbolics L & G machines were 32 + 4 tag for data, 28 + 8 tag for address. Ivory was 32 + 8 tag for data and I think the same for address