freenode/#lisp - IRC Chatlog
Search
14:46:17
Xof
fiddlerwoaroof: well, I'm less certain than I used to be about the outwardly-portable conservative interpretation of the spec (and other developers are more radical in various directions than I am)
14:46:40
Xof
fiddlerwoaroof: but you can make progress by making your own method combinations with the * method-group
14:52:37
mrblack
edgar-rft, I don't think I got to the "list" function with that syntax, but I get your point
16:18:28
fiddlerwoaroof
Xof: yeah, although I'd think that the same reasoning that allows * to "ignore the rules" should apply when * is part of a qualifier pattern
16:36:01
mrblack
I'm trying to understand this function: https://hastebin.com/onugivohev.pl . What is does: tells me if there's and object on a given location. I understand what "assoc" and "cadr" are doint. What I don't understand is where the value for the parameter (obj) comes from, what is its value?
16:39:31
jackdaniel
this is a good question for clschool (again ,p). remove-if-not takes two arguments: a predicate and a sequence
16:40:09
jackdaniel
then it applies each element in the sequence to the predicate (your obj), and if predicate returns T, element is kept, otherwise it is removed from said sequence
16:40:43
jackdaniel
so remove-if-not returns a sequence with all elements in it which met the predicate
16:41:09
jackdaniel
as of asking questions, sometimes it is worth waiting a little more or try things by yourself.
16:41:35
jackdaniel
mrblack: I believe reading this resource will be beneficial to you: http://catb.org/~esr/faqs/smart-questions.html
16:43:53
pfdietz
One thing to be clear about: remove-if-not is nondestructive. It does not modify its argument (although the return value may share structure with that argument).
16:44:37
jackdaniel
mrblack: remove-if-not applies function at-loc-p to elements which are in the second argument
16:45:19
pfdietz
All lisp variables can be thought of as pointers (although for numbers or characters, the things being pointed to can be copied at any time, at least conceptually).
16:46:53
minion
mrblack: please see gentle: "Common Lisp: A Gentle Introduction to Symbolic Computation" is a smoother introduction to lisp programming. http://www.cs.cmu.edu/~dst/LispBook/
16:47:18
pfdietz
What that code is doing is removing every object from the sequence objs for which the loc of that object (as defined by the association list obj-locs) is eq to loc.
16:47:35
minion
more gentle than Land of Lisp? It has cartoons: An error was encountered in lookup: Parse error:URI "https://www.cliki.net/more%20gentle%20than%20Land%20of%20Lisp?%20It%20has%20cartoons?source" contains illegal character #\? at position 84..
16:50:11
pfdietz
Could also write (remove loc objs :key (lambda (obj) (cadr (assoc obj obj-locs))) :test 'eq)
16:50:12
mrblack
anyway, what I'm not understanding is here does the "obj" the appears in the the definition of at-loc-p(obj) comes from... because it is not entered by the main function, which have these arguments: "(loc objs obj-locs)"
16:51:05
pfdietz
mrblack: that "obj" is a formal parameter of the internal function defined by the labels form.
16:51:43
mrblack
pfdietz, but what is it's value gives its value in (cadr (assoc obj obj-locs))? what does it do????
16:52:19
pfdietz
remove-if-not calls at-loc-p on each element of the sequence. For each call, obj is bound to that element.
16:52:37
pfdietz
So, if objs was the list (a b c) then at-loc-p would be called on a, then on b, then on c.
16:52:56
Bike
Okay, so say you have (labels ((oneplus (x) (1+ x))) (mapcar #'oneplus '(1 2 3))), do you know what that would return?
16:55:46
Bike
(mapcar #'1+ '(1 2 3)) is kind of like (list (1+ 1) (1+ 2) (1+ 3)); mapcar calls the 1+ function on each element of the list.
16:56:41
Bike
mapcar calls oneplus on each argument the same way (mapcar #'1+ ...) would call 1+, and puts the results in a list.
16:56:57
Bike
so (labels ((oneplus (x) (1+ x))) (mapcar #'oneplus '(1 2 3))) would also return (2 3 4).
16:57:36
pfdietz
oneplus is called more than once, and on each call 'x' is bound to a different value (1, then 2, then 3).
17:02:09
Bike
remove-if-not calls its function argument on each element of the list it's given in the same way. so that's where the obj argument comes from.
17:05:58
Bike
No. Listen. (remove-if-not #'at-loc-p objs) is a function call. the REMOVE-IF-NOT function receives two arguments, #'at-loc-p and objs. #'at-loc-p is a function and an argument. that's the "function argument" i meant.
17:06:26
Bike
So with (remove-if-not #'at-loc-p objs), remove-if-not will call the at-loc-p function on each element of the objs.
17:07:27
pfdietz
In C, you can pass function pointers to other functions. This is something like that.
17:08:47
pfdietz
#'at-loc-p is a value that can be computed before calling at-loc-p. It doesn't come from a call to that function, but rather is something like a pointer to that function.
17:10:12
pfdietz
It might be helpful to consider a case where the function being passed is defined by defun, rather than inside another function using labels.
17:10:47
mrblack
I don't know, man, this book feels a little unfair. He/She trows a of of things at me... I don't know it it's all like that. But this "recursion hell" (don't even know if that is recursion) should be better explained.
17:23:53
pfdietz
The labels form has the definition of at-loc-p, but that definition isn't invoked up there. It's just defined there.
17:24:38
pfdietz
Execution falls down into the body of the labels form, which is the call to remove-if-not. THAT function then calls at-loc-p on each element of the sequence objs.
17:25:28
pfdietz
And the value returned by the call to remove-if-not is the value returned by the labels form, and then from the call to objects-at.
17:26:36
pfdietz
A function definition, like that in labels, doesn't start executing the function, it just wraps it up in a nice package that other things can call.
17:35:38
pfdietz
One tricky thing there you should understand: where do loc and obj-locs come from inside the definition of at-loc-p?
17:36:50
mrblack
pfdietz, I think those are parameters supplied from outside the function... either user input or from another function
17:37:00
pfdietz
Those are the reasons that code is using labels, rather than defining at-loc-p outside in a defun.
17:38:18
pfdietz
So each call to at-loc-p is seeing those same two variables. Unlike the parameter obj, which is new on each call to at-loc-p.
17:40:48
pfdietz
Functional programming basically means (1) no assignment statements or other operations with side effects, and (2) using functions as values. This example is functional programming, yes.
17:42:42
pfdietz
assoc looks up an element of an association list; cadr pulls out a value from that element, and eq compares. No objects are being modified, no variables are being assigned to.
17:45:27
pfdietz
Lisp *does* support imperative (the opposite of functional) programming. It has destructive operations and assignments. But this example does not use any of that.
17:47:26
mrblack
lisp is so different it is like learning Japanese sometimes :P Only dabbled with C and Pascal before
17:49:37
mrblack
I like Pascal, but it doesn't have much use. My professor used to teach algorithms for a while (it was actually a Portuguese "translation" people here use to teach newcomers)
17:49:56
pfdietz
Lisp lets you do something new, though: you can define a function inside another function, then return it. This is illegal in Pascal; there functions can only be passed "downward" as arguments to other functions, not stored or returned. There's an implementation reason for this (not important now).
19:16:49
emaczen
I don't have experience with gdb when writing a C program either... but thats what you usually see
19:17:11
makomo
johnjay: use emacs along with org-mode to write your notes and git to version control them, that's about it :D
19:18:08
emaczen
johnjay: ask in #emacs but look at magit mode for convenient key bindings for common git commands
19:19:53
johnjay
makomo: i thought you had a system for annotation source code which i've been thinking about lately
19:20:21
johnjay
i hate the bs inline stuff of javadoc and oxygen where you put @doc_string_with_long_name lots_of_text every other line
19:21:38
makomo
johnjay: ah, nope. another benefit of having your notes in plain text is that they're easily searchable using tools like grep, etc.
19:22:13
johnjay
makomo: i did come up with one idea though. You've heard of literate programming right?
19:22:48
johnjay
instead you make a literate prog file which has notes, and mentions only a subset of lines of the source
19:23:01
johnjay
then when you process it you just match it line-by-line to the source file to check it
19:23:34
johnjay
so for example if you have lines A,B,C,D in your file then your literate notes produce only A and C
19:23:50
makomo
johnjay: what does "check" here mean? if i'm understanding correctly, wouldn't you have to maintain the alignment of the positions of text within both of the files?
19:24:28
johnjay
the idea is not to be perfect but just to have some kind of notes that can match the source
19:24:56
makomo
like literally have parts of the source in those "note files", just for the purposes of matching?
19:25:20
johnjay
if your file is #include int main() { printf("hello"); printf("world"); return 0; }
19:25:30
jcowan
pfdietz: Technically a program can change state and still be functional if the state is not visible to the program
19:25:47
johnjay
then your literate notes might say "this is a file that prints hello with the lines printf(hello); printf("world");" then it matches those two
19:25:56
jcowan
a program that does a debug-print operation on the console is functional if (as usual) there is no way to read back console output
19:26:02
johnjay
the only edges case i thought of is what if you repeat a line which changes something
19:26:30
johnjay
makomo: right because you can add or delete lines in a source file, that's relatively common with source control
19:27:05
makomo
johnjay: right, but you still have to keep them in sync, although not fully, just in parts
19:27:24
johnjay
if you just have the lines hello and world from my example you can still keep it in sync
19:27:48
jcowan
another case is a program that has been instrumented to update a profile counter when some function is called; since the profile counters are invisible to the code, the functions are still functional
19:28:34
makomo
johnjay: i guess the details would then depend on the matching algorithm or whatever
19:29:30
johnjay
e.g. between printf('hello') and printf('world') 10 lines of Qt code were added or something
19:30:47
makomo
same, but i always wonder whether literate programming is feasible. it seems like a good idea to me, but i've never actually tried it on a bigger project
19:31:12
johnjay
yeah that was why i thought this might work, because with literate programming any change necessitates updating the literate source
19:31:27
johnjay
but maybe if you ask for less you can use it this way, to just kind of maintain some basic notes on something
19:32:56
makomo
it's a pretty nice talk, i've watched it multiple times https://www.youtube.com/watch?v=Av0PQDVTP4A
19:34:19
johnjay
i guess the essence of my idea was that the more fixed the code the more literate you can make it
19:34:57
johnjay
so maybe you could have 3 levels: full lp for old unchanging code, my hybrid version for code that's mostly done , and then like notes matching to specific line numbers for WIP
19:35:46
makomo
the hybrid version that uses matching could somehow work, i guess. but the last approach would be too burdensome i think
19:36:21
makomo
right, but that's even worse, because then you have to keep changing those line numbers
19:38:55
francogrex
hi can I make a region executable by using mprotect? for example if i use cffi foreign-alloc or make pointer, can I make it protected and executable?
19:39:28
johnjay
there's a game programming project i'm familiar with and i despair of any kind of documentation for it
19:40:00
johnjay
basically you have constant churn as bugs are discovered and fixed so nothing is really "safe" from modification
19:41:30
makomo
johnjay: yeah, it gets hard to keep up the "book" up to date with so many modifications
19:42:20
makomo
that's why i feel like literate programming is great for stuff that has been "solved", i.e. the idea was thought through, a good design was developed and it won't be changing much
19:42:43
makomo
there are a few literate books: knuth's tex, elliptic curve crypto, understanding mp3 and physically-based rendering
19:43:22
makomo
all of them talk about something "solved", i.e. something that has been analyzed, discussed, specified, etc.
19:44:27
jcowan
Sure it does. You just have to accept down in your bones that changing the prose is just as important as changing the code.
19:44:32
myrkraverk
johnjay: I've compiled noweb on arcane systems before, and I don't remember if I had any problems.
19:45:40
makomo
also, that, yes. the demands for LP are a bit higher than usual. you have to be a good writer
19:46:01
myrkraverk
jcowan: it's a different skillset. Many programmers can't write comprehensibel english.
19:50:50
johnjay
it specifically is only using lp in small pieces for code you know fairly well won't change
19:53:50
minion
nixfreak, memo from Jachy: https://github.com/t-sin/one (example of using CL with bash one liners)
19:55:26
pjb
nixfreak: also, with normal REPL you can use (DRIBBLE "file") but it doesn't work with slime since it uses custom threads to implement the REPL itself. One could patch swank to log the expressions (and results) like with DRIBBLE.
20:05:36
pjb
nixfreak: with slime, you have the whole slime buffer keeping the history. You can also just save it with C-x C-s
20:12:44
void_pointer
Only thing to be aware of is that when you use a previous code at the REPL, you can't add newlines to it
20:19:52
fiddlerwoaroof
emaczen: typically one doesn't use gdb on a common lisp program, unless you're doing ffi stuff
20:22:41
flip214_
Can I get the current input position (in bytes) from CXML? I'd really like to create an index (tag => position, length) into a large XML file, and then do "random" IO on it.
20:23:32
fiddlerwoaroof
Well, you can try starting gdb and then using attach <PID> to attach to an existing process
20:24:21
fiddlerwoaroof
However, I've found that various things about sbcl and ccl can make this really painful
20:25:06
fiddlerwoaroof
You can also do `gdb my_program` and then `run may arguments ...` inside gdb
20:26:10
fiddlerwoaroof
Finally, there's `ulimit -c unlimited; my_program; gdb my_program core_file` which lets you inspect the state of a process at the time that it crashed
20:26:48
fiddlerwoaroof
The most useful gdb command is `bt` that shows a backtrace of the program being debugged.
20:35:21
flip214_
jasom: I tried to use evil mode a few times in the past... but there's too much that doesn't work to make me comfortable.
20:37:37
emaczen
Does mallocing a pointer inside a lisp function and freeing it from the calling function cause a memory leak?
20:39:04
Bike
a memory leak is when you fail to free memory. so if there's some way for things to go so that the freeing never occurs that's a leak
20:39:15
void_pointer
As long as it is freed somewhere, it shouldn't cause a memory leak. That all said, in that case (as well as pretty much any case), you do need to make sure you have things setup such that it will for sure be freed once but no more than once because double free doesn't go well
20:39:29
Bike
for instance, if the mallocing function signals an error, which goes to the debugger, and then you quit the debugger back to the repl
20:41:26
void_pointer
or if you have the pointer in some containing object and put a finalizer on the containing object that has a copy of the pointer it will run free with (one does then need to be careful to not free it manually without removing the finalizer or otherwise disabling it in order to avoid double-free)
20:42:25
flip214
well, freeing in the outer function has the problem that the pointer to the memory-to-be-freed has to be communicated somehow... and if the inner function crashes before that, the outer won't know what to free
20:42:47
void_pointer
another issue is if the pointer points to a structure that itself has malloc'ed pointers. Freeing the first pointer doesnt reclaim the memory of those it was pointing to
20:42:51
emaczen
Well my this function returns a pointer, and then at the end of the calling function it frees the pointer -- I don't see how I can leak that much...
20:45:19
void_pointer
The one exception here is if you are using something like bdwgc and you use its malloc in which case you would be OK. If your implementation uses bdwgc or something similar and you are using the malloc the implementation provides, then there is a good chance you are using its malloc instead of libc malloc.
20:46:02
flip214
void_pointer: another exception is using hierarchical memory pools, like subversion does.
20:46:09
void_pointer
ECL uses bdwgc last I checked. SBCL, CCL, and CMUCL don't. Don't know about Clisp or Clasp
20:46:52
nirved
void_pointer: in slime repl - delete the last closing paren, and then can edit the rest with adding newlines
20:47:28
Bike
emaczen: if this is leaking, there is a path from the malloc that does not lead to the free, which you will have to find and excise.
20:47:33
void_pointer
emaczen: then unless you are one one implementation only, you can't assume much. Also, that is good you don't have to worry about pointer nesting.
20:50:24
fiddlerwoaroof
I think there's a way to transparently replace malloc with one that warns you about unfreed memory
22:50:21
oni-on-ion
the 'random bits' of memory, is this like that from the computer just powering up the chips? i mean, they dont start at 0 right, they've got to be 'set' in software?
22:50:54
phoe
in general, memory can be allocated and freed in arbitrary parts of the program; it's hard to tell malloc "warn me if I don't call free on this piece of memory by the time I leave this lexical/dynamic/??? scope" unless you employ other tactics, such as unwind-protect
23:29:25
no-defun-allowed
i made #netfarm (which is bridged to the matrix #netfarm:matrix.org) cause most of the talk around it isn't useful to the average lisper imo