freenode/#lisp - IRC Chatlog
Search
21:45:46
_death
(defun elevator (number &rest divisors) (floor number (reduce #'* divisors :initial-value 1)))
21:50:29
stylewarning
shrdlu68: the hashlife algorithm from gospers compressing space and time paper
21:52:06
shrdlu68
Mine's so simple, no curses or implementation-specific stuff. and should run in any terminal with primitive support for ANSI control sequences.
21:56:16
shrdlu68
I know, wanted to make this with as little dependencies as possible, which is none.
21:57:35
stylewarning
shrdlu68: rake in all the deps you can get your mitts on! And help fix open source bugs...
21:59:14
didi
So I have a collection of elements that might have some duplicates according to a "samep" function. I want to merge these duplicate elements, by collecting their cdrs into an arbitrary element key. Say I have the collection ((a . resta) ... (b . restb) ...), and (samep a b), I want to merge a and b so the result will be ((a resta restb) ...). Is this a known operation? I am thinking of calling it `merge-duplicates'.
22:04:28
_death
stylewarning: too personal.. I'm guessing stuff on my github is like 10% of my code-at-home
22:04:34
drmeister
Does find-class need to be fast? What if I implemented find-class with an alist - I'm thinking about lockless data structures.
22:06:24
stylewarning
didi look at the function EQUIVALENCE-CLASSES here https://github.com/tarballs-are-good/quickutil/blob/master/quickutil-utilities/utilities/sequences.lisp
22:08:39
Fare
next year ICFP is colocated with StrangeLoop, and quite possibly the Scheme Workshop with it.
22:08:47
pjb
(mapcar (lambda (class) (cons (car (first class)) (reduce (function append) class :key (function cdr)))) (com.informatimago.common-lisp.cesarum.list:equivalence-classes '((1 a) (2 b) (1 c) (3 d)) :test (function eql) :key (function car))) #| --> ((3 d) (2 b) (1 c a)) |#
22:09:08
stylewarning
didi so the call will be something like (mapcar ‘combine-lists (equivalence-classes ‘samep list))
22:13:07
stylewarning
_death it would be cool if you tried to make some public. Most of my lisp-random is garbage
22:15:10
stylewarning
Gems like https://bitbucket.org/tarballs_are_good/lisp-random/src/a595eb662c2dce87f362dd0dd2541a93efe9c902/cxr.lisp?at=master&fileviewer=file-view-default
22:19:38
_death
stylewarning: I sometimes lisppaste/gist snippets.. as in your case, some of them grow to become libraries.. maybe in the future I'll decide to publish a "revised" history
22:50:04
_death
the gifs themselves are pretty cool.. e.g., http://london.harekiet.com/compo/index.php?nick=dila
2:00:11
emaczen
I have a cryptic error from SBCL which says: the value 65583 is not of type (UNSIGNED-BYTE 16) when binding SB-ALIEN::VALUE
2:20:36
White_Flame
but since (LOAD #P"/home/.../.cache/common-lisp.....") is in there, one of the first orders of business is to rm -rf ~/.cache/common-lisp/ and rebuild everything
2:21:12
White_Flame
something might have gotten built and stuck around in your fasl cache that isn't compatible with the version you're running now
2:26:13
White_Flame
I have a feeling that the "/ps/index.js" is being loaded as something that it shouldn't
2:27:40
emaczen
White_Flame: I have a program that generates programs, and then I do (asdf:load-system :program-name)
2:30:35
White_Flame
basically, did you ever install multiple sbcls? as in, maybe one from apt and one from source, or multiple different source builds hanging around?
2:31:25
White_Flame
iqubic: because functions don't transform code, and always evaluate their arguments
2:32:52
White_Flame
and if functions get too unwieldy to use, ie (my-func (lambda (x) ...) (lambda (y) ...)) then maybe you should use a macro to generate the code body instead
2:33:52
emaczen
iqubic: then you can try it yourself and extend it to anaphoric cond and anaphoric case and anaphoric typecase
2:34:06
White_Flame
right, 'if' via function is (iffunc test-val (lambda () then...) (lambda () else...)
2:35:28
emaczen
usually if or cond is a "special builtin" I can't remember the terminology, but then the one that is not "builtin" could be implemented as a macro expansion of the other
2:37:01
emaczen
White_Flame: Ok, so these 3 new programs are about 3 times the size of my other programs just by looking at my databases
2:37:29
emaczen
White_Flame: I don't think that should really matter, but it is the only real difference that I am aware of
2:39:02
iqubic
So, I'm writing my emacs config, and I'm noticing a certain pattern crop up a fair few times. I just want to install a package with use-package and not configure it.
2:40:22
White_Flame
lots of people here (like me) know CL and don't really know the ins & outs of emacs lisp
2:42:53
emaczen
From my experience without doing much work, SBCL gets me faster code but CCL will generally just work (more robust)
2:43:34
White_Flame
the only non-robustness I've hit with SBCL is running it on windows a long time ago
2:43:55
emaczen
Fare: They aren't really failures, I just get the occasional error like this one I have now
2:44:18
emaczen
Maybe CCL is supposed to give an error some of these times, but it just doesn't -- I don't know
2:44:53
Fare
I remember having concurrency issues in sbcl, but that was long ago. The only lingering issue I had was some code that triggered bad behavior in its optimizer, leading to explosion during flow analysis.
2:45:07
White_Flame
Fare: <emaczen> I have a cryptic error from SBCL which says: the value 65583 is not of type (UNSIGNED-BYTE 16) when binding SB-ALIEN::VALUE [19:22:08] <emaczen> http://paste.lisp.org/display/356871
2:45:51
White_Flame
Fare: heh, I remember the slow-macro-expansion behavior. Got killed in build time for a 15+kloc macro expansion
2:46:30
Fare
I remember issues with FFI where the ABI said that high bits should be ignored, but SBCL failed to clear them.
2:47:19
White_Flame
yeah, but when you rebuilt, it put a .fasl there again and loaded it, if you got the same error
2:47:57
Fare
but yeah, I don't think there are a lot of paid sbcl maintainers... last I knew, there was one at Google
2:54:01
iqubic
So, if my functions relies on symbol "foo" and symbol "foo-mode" is there a nice way to get them both, while only passing one in as a parameter.
2:56:22
iqubic
I know I could do (defun simple-use (package-name mode-name) (body here)), but that seems like overkill because I will always call that function like such:
3:00:06
White_Flame
easiest would be to make your window wide enough. :-P That, or nose around the emacs menus
3:05:35
emaczen
I could probably get it through the machine I am using here, but I'll do that in a bit
3:48:06
z3t0
How would I turn this into an object that I can write to a file? Do I simply write this binary data
3:49:48
White_Flame
yes, you can open a file with :element-type 'unsigned-byte, then write-sequence should shove those bytes through
4:06:21
iqubic
Is there a way to take symbol like "foo-bar-baz" and get the symbol whose name is just that with "-mode" appended to the end?
4:07:39
iqubic
So have a function/macro that takes the symbol "test" and returns the symbol "test-mode"
4:11:47
White_Flame
and by using a symbol for the suffix you want to add, it ensures it's using the proper case
4:12:39
z3t0
in python there's {} inside which you can do normal python computation, maybe i should just write a macro
4:16:44
White_Flame
if you need to build a string, FORMAT is the usual go-to, unless you need to worry about performance
4:17:25
Zhivago
And you can write your own macros and functions to do what you want in the way you want.
4:18:18
Zhivago
One alternative to concatenation might be to instead print and capture the output in a string.
4:20:06
pjb
(defun cl-user::ev (stream argument colon at &rest parameters) (declare (ignore colon at parameters)) (prin1 (eval argument) stream)) (format t "Foo ~/ev/ bar" '(+ 1 2)) #| Foo 3 bar --> nil |#
4:21:03
z3t0
For now i am just converting it to strings and then later i'll write up a macro so i dont have to do all of this
4:21:12
pjb
And silly, but that's what you get for asking equivalents from Python (or any other language for that matter).
4:21:56
pjb
That said, there are libraries for interpolated strings in CL… I don't know any code using them.
4:24:12
White_Flame
You could also pour bleach into your eyes and gargle broken glass, just sayin'...
4:24:28
pjb
(But from the examples of cl-interpol, #?"" builds a run-time expression, so it's useless (ie. no read-time evaluation, no string literals).
5:41:27
beach
theemacsshibe[m]: Lesson 1: we have written the name of the language "Lisp" for the past few decades. When you write LISP, most people here think of some very early version of the language.
5:46:24
beach
theemacsshibe[m]: Most people here recommend you use either SBCL, CCL, or ECL for your Common Lisp implementation, and Emacs+SLIME as your development environment.
5:47:28
theemacsshibe[m]
I already use Emacs+Slime and have both SBCL and GNU CLisp (man page didn't have a capitalisation for that so idk) so that seems alright
5:50:19
uint
Xach: I'm not sure if I'll be working on it yet. Just an idea right now. I'll reupload it when/if I have something that works!
6:20:40
|3b|
more or less same as writing a function, with some extra options for the argument list, just remember the input it gets is different from what a function would get if evaluated in same context
6:36:26
iqubic
Does the reader keep expanding macros until there are none left? That's the behavior I need. That's also why a plain function won't do.
6:38:37
|3b|
macro code is just normal CL code, works like any other. code in expansion of a macro is just normal CL code, works like any other (including expanding any macros in it)
6:39:15
|3b|
ACTION isn't sure if you meant a macro used in the definition of the macro, or one in the code it returns
6:44:11
Shinmera
You can be unspecific if you think it helps, but please don't just state blatantly false things. That's never helpful.
6:44:14
|3b|
simplifying is OK, simplifying until it is wrong is bad (at leaast if there is something comparably simple that is still correct)
6:45:00
|3b|
ACTION has the impression getting the distinction between read/evaluate/compile right helps a lot when learning CL
6:47:50
|3b|
ACTION doesn't think it is too important to learn it now, just that you don't learn some of it wrong now :)
6:56:43
|3b|
though now that i think about it, if you are writing macros it may be time to learn about it soon. backquote is one of the places where it starts to matter
7:20:41
|3b|
if i have MACROLETs A and B and i want B's expansion to depend on arguments to enclosing call to A, is there some way to do that besides emulating compiler-let with symbol-macrolet and macroexpand?
7:23:56
|3b|
but something like (a 'x (b ...)) and (a 'y (b ....)) where the 2 calls to B expand to diffferent things
7:25:12
|3b|
trying to generate code based on a description of a (nested) data structure, so A would change the context to a specific child, and B would be the part that does the work and needs to know which part of the tree it is looking at
7:25:56
|3b|
ACTION thought A would expand to a macrolet or symbol-macrolet that stores the context, then B macroexpands that to get the current value
7:26:13
flip214
have A bind some special variable while MACROEXPANDing its body, and make B look at that special?
7:26:58
|3b|
A binding a special during macroexpansion is compiler-let, which didn't make it into CL :)
7:27:59
|3b|
this is all happening at runtime, but needs to be fast, so i want to generate specialized code at runtime
7:29:03
|3b|
flip214: more general case would be (a 'z (loop for i below 10 do (b i ...))) or things like that
7:29:43
|3b|
White_Flame: don't think those help, they aren't even required to do anything and i'd like the code to be at least theoretically portable :)
7:30:44
White_Flame
it's hard to imagine even with manual MACROEXPAND calling to solve it without proper code walking, too
7:31:38
|3b|
so i have local macros that need to communicate with eachother during expansion, and if i remember correctly, the way to do that is use symbol-macrolet (or normal macrolet) to store values in the compilation environment, and macroexand to extract them
7:32:49
|3b|
but B could just do (case (value-from-a) (x ...) (y ...) (z ...)) if there is some way to implement value-from-a
7:32:59
White_Flame
hmm, if A created a body that contained (macrolet ((b ...))) I wonder what sort of evil you could do without infinite recursion
7:36:24
|3b|
possibly factoring out the A from each level into separate macros, so they don't have to be nested, though i don't think that matters too much
7:36:54
|3b|
(both are being generated, so don't need to be human understandable, though it would be nice for debugging)
7:41:28
|3b|
though now i'm thinking i may want communication in the other direction too, so A can do something with all the parts for which B wasn't called, not sure i can do that even with macroexpand
7:45:57
|3b|
pjb: overall problem: given a spec for a recursive data structure (names + types + offsets in memory), i want to generate code that efficiently writes values into memory corresponding to the names. the spec isn't known until runtime, and may change over time.
7:46:39
|3b|
if a name is given that doesn't exist in the spec, the value can be discarded. if a name in the spec isn't written to, i'd like to be able to write a default value (possibly from the spec)
7:47:19
pjb
Instead of writing something like: (macrolet ((define-foo (name) …) (get-foo (name) …)) (define-foo bar) (define-foo baz) (+ (get-foo bar) (get-foo baz))) write (macrolet ((with-foo (name &body body) `(macrolet ((,(scat 'get- name () …)) ,@body)))) (with-foo bar (with-foo baz (+ (get-bar) (get-baz)))))\
7:47:23
flip214
|3b|: is speed such a concern that some sane representation of the structure, and some "interpreter", isn't fast enough?
7:48:05
|3b|
flip214: yeah, this is happening 10s of thousands of times per second, and needs to leave room for lots of other work
7:48:37
flip214
|3b|: how about the CL-PPCRE approach? this takes some variable input, and build some closure chain from that.
7:49:24
|3b|
ACTION also wants to be able to have type declarations on the source data, so for example it doesn't need to spend time determining each value in a specialized array is a single float
7:51:15
|3b|
ACTION possibly wasn't clear... i have an output spec at runtime, and an input spec at compile time, and runtime compilation to combine the 2
7:51:15
pjb
Now, you could use (eval `(some-dsl-form ,some-data)) but it's clearly inferior to (take-some-run-time-data some-data) ;<- a functional API.
7:51:44
pjb
|3b|: I'm not surprised, since this macro example doesn't match your needs at all. You don't want macros.
7:52:38
|3b|
how do i communicate that parts of it are simple-array :single-float (3), other parts are (unsigned-byte 32), etc?
7:53:30
pjb
(spec (part one (simple-array single-float (3)) :check nil) (part two (unsigned-byte 32) :coerce t))
7:57:21
|3b|
probably not corresponding to the spec data, since they weren't written at the same time
7:57:49
flip214
as one example, "just" build a big "(DEFUN my-interpreter (input) ...)" form, and EVAL it.
8:00:08
pjb
Often, the dispatching is very lightweight, compared to the canned processing, so there's very little gain to generate lisp source and compile it.
8:00:18
|3b|
ACTION already does the job directly, i have something that takes a nested hash table of the names -> data to write
8:01:11
|3b|
but that is slow, since it does hash lookups and pointer calculations for each value, and tends to have unspecialized code so does extra type checks etc
8:01:13
pjb
Well, if it's too slow, then you can try to generate code to do it instead of doing it with those indirections. Be careful to remove the maximum of indirections in the code you generate.
8:02:06
pjb
Yes. You can fetch the data from the table, and compute the pointers in generate, and generate source code that contains only literal and pre-computed values.
8:02:42
pjb
But given that you're doing I/O, it's not sure you will gain anything. Have you profiled the current code?
8:03:52
|3b|
only IO is memory writes, and the profile did show lots of hash table and various sbcl internals from lack of declarations
8:04:26
|3b|
ACTION is stuck on windows with not very good profiler, so not completely sure, but fairly confident that was all the code i'm trying to optimize
8:05:26
|3b|
now i need to be able to specify to the code generator, what data it should be writing and how to access it
8:07:04
pjb
This is something that's so natural to do in lisp, that I must have a dozen of such generators around. But I'd have to locate them…
8:07:59
pjb
This (name type offset) data is the source code for your generator. The lisp source will be the compiled code for that DSL.
8:08:56
|3b|
generating code from the name+type+offset isn't the part i'm having a problem with, it is matching it to the lisp data to be written
8:09:11
pjb
and an interpreter is any function taking some data, and doing something according to that data (plus some other "input" data), while a generator (compiler) is any function that takes that data and generate a function that takes input data and produce the wanted results.
8:09:52
|3b|
so i want to write a DSL that takes names and lisp data, and matches them to the names in the name+type+offset spec
8:11:50
|3b|
or "following applies to struct at location named 'bar" with a set of "write value Y to location 'baz" which applies to 'baz in that struct
8:11:54
pjb
You want lisp code that concisely DOES write the value X to the location named by foo. ie.: (SETF FOO X).
8:13:08
pjb
You don't know anything bout foo at code-writing, since it will be specified at run-time!
8:13:32
|3b|
so i guess more precisely, the code i write would be saying "write X to location named by 'foo if it exists, otherwise write the default value specified for 'foo"
8:15:04
|3b|
then at runtime, when the spec was available, it would be transformed into something like (setf (cffi:mem-ref 123 some-type) x)
8:16:05
|3b|
where X would be a parameter passed to the generated function, or some function of a parameter
8:16:24
|3b|
and i could do things like calling B in a loop to write elements of an array or whatever
8:17:54
|3b|
and A would say "i'm writing to the struct at slot 'bar" or "i'm writing to the array at slot 'bar" (so really 2 different A, though i guess i could figure out which based on the spec)
8:18:51
|3b|
and if there is no slot 'foo or 'bar, no code would be generated. and if there is a slot 'foo2 for which i hadn't specified anything to be written, some default value would be written by the generated code
8:20:21
|3b|
so as far as i can tell, the part processing the "write X to Y" side needs to either be a complete code walker, or have some macros to implement the writing DSL
8:20:51
|3b|
ACTION is probably working too close to my complexity limits though, so other suggestions are welcomed :)
8:29:22
flip214
|3b|: how about writing some lisp code that translates your spec to the structure definitions used with alien code, and then use (slot-value 'foo) etc. to access the data?
8:29:59
|3b|
and as far as performance needs, i want to be able to write millions, probably tens of millions of values per second, while leaving as much time as possible for deciding which values to write and to actually use the data
8:31:27
|3b|
writing to slots that don't exist is allowed, and something happens to slots that aren't written
8:32:07
pjb
Of course, at any time in those compile-* functions, you can have non-literal specifications, ie. names that you will lookup (and call one of those compile-* function recursively).
8:32:23
|3b|
i know the exact offsets already, so specifying those to CFFI so foreign-slot-value can give them back to me is just extra work
8:33:00
pjb
And you could just look how CFFI is implemented and do the same. (Or why not, just call the CFFI internal functions!)
8:37:01
pjb
the defparameter should come below, it was written first, as a specification of the DSL.
8:37:53
|3b|
before running the program, i want to write some code to write values to named locations in memory, where the names are hierarchical, so i might have in C terms, foo.bar[123].baz
8:38:06
pjb
Which is then called at run-time to store the data (here a literal vector, but it could be some other run-time data).
8:38:35
|3b|
at run time, i want to determine the available names/hierarchy and corresponding locations, then turn the previously written code into optimized code to do actual writing
8:39:27
pjb
In compile-store-specification, in the otherwise branch, you will add a (gethash (first specification) *named-types*) and if found, call compile-store-specification recursively on the obtained type value.
8:39:32
|3b|
that set of names/hierarchy might change, in which case i need to recompile the optimized writer function, without modifying the previously written code
8:40:17
pjb
Analyzing the specifications for your named data types, and incorporating in a hash-table, I assume you can do it yourself!
8:40:42
pjb
And again, this is already implemented in CFFI, so I don't understand why you don't just call the CFFI internal functions…
8:41:26
|3b|
my problem is that i want to pass arbitrary data, possibly from multiple sources, possibly not using all of it
8:41:44
pjb
Look, I won't answer anymore question until you provide a 100-page PDF with the specifications of your DSLs.