freenode/#lisp - IRC Chatlog
Search
2:20:18
pierpa
LET establishes a new binding, that is it creates a new variabl. SETF modifies an existing place
3:11:15
jmercouris
newcoder: they're just saying, put whatever you wanted to do with X in place of <body>
3:20:23
Bike
when you do (let ((x 5)) some stuff), in the course of some stuff, x will be 5 okay bye.
3:44:05
aeth
jmercouris: the connection did not die, that's Ping Timeout or Connection Reset by Peer
4:21:48
drmeister
Are there any multi threading wizards about? I'm trying to adapt beach's fast generic function approach to multi-threading - my first attempts all deadlock.
4:23:11
drmeister
When I made clasp multi-threaded it was pretty straightforward. Attach a read/write lock to sensitive objects, write protect resources when I was writing them and read protect them when I was reading them.
4:24:11
drmeister
I've implemented this algorithm for generic function dispatch that involves compiling a dispatch function when it's needed.
4:25:26
drmeister
Each generic function maintains a 'call history' - an alist of selectors and effective methods.
4:26:01
drmeister
When the call-history changes, the current dispatcher is invalidated (it's pointed at the function 'invalidated-dispatcher')
4:26:50
drmeister
If a generic function is called and it enters 'invalidated-dispatcher' it compiles a new dispatch function based on the call history and points the generic function at this new dispatch function.
4:27:08
drmeister
So a call to a generic function can cause the generic function to change its internals.
4:27:16
jmercouris
drmeister: I've read your messages several times, and I still don't understand what you're trying to do
4:27:26
drmeister
Now - get all this working in a multithreaded environment where any thread can call any generic function at any time.
4:27:45
jmercouris
what is generic function dispatch exactly? you just want to execute functions from a pool of threads?
4:28:34
jmercouris
drmeister: I'm not sure, possibly and I don't know the term for them, I'm still quite new to common lisp
4:29:04
drmeister
No problem. Generic functions are like C++ virtual methods - but you can dispatch on any combination of arguments.
4:29:32
drmeister
C++, Python, Smalltalk - these are all 'single dispatch' languages. You select a method based on the class of one argument.
4:29:59
drmeister
Common Lisp uses generic dispatch - you can select methods based on any combination of arguments.
4:31:00
drmeister
Then you can write methods like (defmethod print-thing ((obj circle) (device printer)) ...)
4:31:34
jmercouris
did you mean to write (defmethod print-thing ((object circle) (device printer)) ..)
4:31:52
drmeister
When you invoke (print-thing x d) the system selects at run-time the appropriate methods.
4:32:09
jmercouris
based on what exactly? based on if you have right object type? or whatever else you want?
4:34:06
drmeister
How it does the type matching is there is a slow path - where it calculates the method from the arguments when it hasn't seen that combination of argument classes. It does this in a very slow, complicated way.
4:34:45
jmercouris
My question to you, is, is there a timing issue that can result in a loop of operations for you?
4:35:10
jmercouris
Like, a dependency on a dependency? I mean, it should be obvious because you said "deadlock", but can you inspect the threads?
4:35:23
drmeister
The way to quickly recapitulate the memoized results is what I've just implemented. It's fancy because it compiles on the fly a new dispatch function that dispatches to the appropriate code with the absolute minimum number of memory accesses.
4:36:04
drmeister
I can inspect the threads - but there are some barriers to interpreting the stack traces.
4:36:46
drmeister
My backend is llvm and I'm using the JIT to generate code and dispatch functions. There is no debug information - not even function names associated with JITted code.
4:37:16
jmercouris
I was about to suggest maintaining several output streams to see the state of the threads as they enter deadlock..
4:37:18
drmeister
I can reliably reproduce the problem - but it changes subtly each time and it takes several minutes to reproduce.
4:37:58
jmercouris
interesting, yeah, it would be very complex to try to visualize what is happening just from the memory
4:38:34
drmeister
I do have quite a lot of logging/debugging code written for this - but I'll have to rewrite it because I didn't write it in the first place to handle multiple threads. Hmmmmm....
4:38:44
jmercouris
I think one of your few options is to try to make a script or something that recreates this problem reliably
4:38:53
jmercouris
because only then will you be able to know how to cause it, and it may give you some hints
4:38:55
drmeister
As I said that I realized I might have an angle on getting per-thread logging messages.
4:42:19
drmeister
I have per-thread dynamic variables and the logging code uses a dynamic variable to store the stream for logging output.
4:42:34
drmeister
I should be able to hack things so that each thread writes out to a separate file.
5:25:04
vtomole
drmeister: I'm trying to implement a lisp intepreter in C, and i'm having a bit of trouble writing the parser. Do I need to implement a function that puts linked lists inside linked lists?
5:28:03
iqubic
Does C have support for heterogeneous data structures? I ask because lisp is basically just one giant heterogeneous data structure.
5:31:25
pjb
drmeister: well, the critical section is the updating of the dispatching functions of the generic functions. This is the only place where you should need mutexes, when you update the generic functions (ie. when classes or methods are changed).
5:33:06
pjb
vtomole: start by writing your interpreter in lisp, it'll be easier. Then you may write a translator for the subset of lisp you used to implement your lisp interpreter in lisp, to translate it to C…
5:35:15
vtomole
I did. I then had to implement cons() in C and I don't think I did it right cause my recursion parsing is not working correctly.
5:35:46
pjb
vtomole: I fail to see the link between implementing cons and implementing a recursive parser.
5:37:12
iqubic
pjb: I think the issue is knowing where the closing bracket of the cdr of a particular cons cell is.
5:38:07
vtomole
Using this as a reference worked for me in Lisp. C is a different animal: http://norvig.com/lispy.html
5:38:23
vtomole
From that page :def read_from_tokens(tokens): "Read an expression from a sequence of tokens." if len(tokens) == 0: raise SyntaxError('unexpected EOF while reading') token = tokens.pop(0) if '(' == token: L = [] while tokens[0] != ')': L.append(read_from_tokens(tokens)) tokens.pop(0) # pop off ')' return L elif ')' == token: raise SyntaxError('unexpected )')
5:38:52
iqubic
In order to parse lisp I would first create an ast of the code, then interpret that ast.
5:39:10
pjb
Perhaps you should read: Lisp in Small Pieces http://pagesperso-systeme.lip6.fr/Christian.Queinnec/WWW/LiSP.html http://pagesperso-systeme.lip6.fr/Christian.Queinnec/Books/LiSP-2ndEdition-2006Dec11.tgz
5:40:42
pjb
And given that lisp objects such as cons cells are such a fundamental and basic layer, it should have been developed and tested heavily long berfore you started writing the parser!
5:41:31
iqubic
I'm not sure I see the issue. Can you share your code with use so that we might help you?
5:42:44
vtomole
I'm basically trying to translate this to C: http://paste.lisp.org/display/356603. Let me organize my code first before I post.
5:44:42
stylewarning
Does anyone have a fix for: Warning (slime): Caught error during fontification while searching for forms that are suppressed by reader-conditionals. The error was: (args-out-of-range "" 0).
6:20:56
vtomole
I'm basically trying to put a linked list inside of a linked list((cons (token, read_from_tokens(cdr(token_list))));, but i'm running into an infinite loop:http://paste.lisp.org/display/356606
6:23:52
iqubic
But yeah, a union is better for that than a pair of strings. What would happen if the strings got mismatched?
6:25:29
iqubic
And a pair of strings is a bad way to store anything. A union is a way better way to do that.
6:26:46
|3b|
ACTION assumes union would be to add tagging, and would store struct cons and anything else
6:27:48
|3b|
other option would be to play tricks with pointers like most native implementations do, but i'd probably avoid that without a lot of knowledge of C spec to avoid undefined behavior, and implementation details
6:28:10
vtomole
Yeah I did that earlier, but that would mean I need to keep track of types so that I can dereference them when I need the value.
6:38:11
beach
I would use a struct for each kind of object and a void* for a field that should contain some other object. And you need to include the type somehow so that you can figure that out at run-time.
6:53:23
|3b|
you would either put the type in all of the structs, use a union to associate the type with all structs
7:51:50
guicho
I don't usually come here unless I beg your collective knowledge. so as expected, I have a question.
7:52:24
guicho
I forgot the name of a cl project for matrix operations. it was on github. the readme stated that one of its main difference from the other libraries is that it overrides the standard operator such as *, + as a CLOS method. Could you identify this library?
7:59:15
guicho
https://gist.github.com/guicho271828/23e5d474adcd9890b9d41b622f458644 these are not what Im looking for
8:34:59
guicho
I hope this is not the case that I literally *dreamed* this library ... and remembering this as if I actually saw it...
11:37:25
edgar-rft
guicho, cl-ana provides its own versions of the basic math functions CL gives you but with the ability to extend them for whatever types you want: <https://github.com/ghollisjr/cl-ana>
11:52:15
whoman
subconsciously thinking, "CL could have already had ability to extend basic math funs if it were golden idea"
11:54:57
edgar-rft
I think the main problem here is that number-crunching needs all speed you can get out of any programming language. A full generic dispatch on every basic math function is way too slow for that.
12:26:40
guicho
edgar-rft, wow, thank you that. yes this is what I was looking for. so this is why keywords like "matrix" nor "array" didn't work.
13:02:50
edgar-rft
guicho, I knew I had read that somewhere, but same problem like you, the internet is way too big and Google is way too ignorant about Lisp.
13:05:12
Josh_2
Most people are ignorant about Lisp. Peoples reaction when I say I like CL the most is normally some form of "ermagurd how could you?"
13:10:41
edgar-rft
Josh_2: that's good because it means you only need some mediocre Lisp knowledge to beat them all
13:16:43
dim
I have the good luck to learn lisp at school, in between C++ and Java. Unfortunately the teacher was so ignorant about it that we only played with cons, car and cdr and we had to answer cryptic exercises of no value. I guess the whole class was disgusted and saw no point in Lisp at all.
13:17:12
p_l
dim: that's common case in the vestigal courses that introduce various forms of programming
13:17:55
p_l
dim: in my case, I believe we had a bit of Prolog instead, don't recall if we had lisp directly, but we had a lisp-derived language (Jess) much later on
13:19:31
dim
Java has ABCL and Kawa too, and Clojure nowadays, if you depend on the JVM to run programs... but anyway