freenode/lisp - IRC Chatlog
Search
11:10:46
pjb
beach: it's clear that uniform reference model simplifies things a lot. This is the "everything's an object' of Smalltalk. And unfortunately, Java distinguishes C-line int from OO Integer. Objective-C Cocoa Frameworks too have a NSNumber class and must inherit C integers since Objective-C is a strict superset of C.
11:12:00
pjb
beach: like in Objective-C, we can in C use a programming style where uniform references are used most systematically. There's some boilerplate, some repeative code to be written, because of the C type system, but this can be wrapped in cpp macros…
11:12:34
beach
Yes, when I still programmed in C, I would use pointers for basically everything (except integers, etc.)
11:13:20
r13l
morning all! is there a supported way to handle signals in SBCL? i’ve been googling & reading docs, but to no avail. found trivial-signals, which appears to be broken, and sb-unix has some stuff vaguely related, but it states that it’s not intended for end users (also, is UTF-8 okay on #lisp?)
11:33:01
jackdaniel
r13l: long story short: (sb-sys:enable-interrupt sb-unix:signame (lambda (signal code scp) (sb-sys:with-interrupts (bla-bla))))
12:06:39
madrik
Are implementations supposed to notify or otherwise enter the debugger when they read a DEFCONSTANT from in a file on successive loads?
12:09:05
shka_
"A constant defined by defconstant can be redefined with defconstant. However, the consequences are undefined if an attempt is made to assign a value to the symbol using another operator, or to assign it to a different value using a subsequent defconstant. "
12:13:02
madrik
So, if I have a string housing a file name that is supposed to be unchanging, should I not use DEFCONSTANT?
12:14:46
madrik
Okay, I checked the glossary in the HyperSpec, and indeed, two objects are _same_ if they are EQL.
12:16:39
loke
madrik: I was going to write the code for it, but it's a few lines... But you can use ALEXANDRIA:DEFINE-CONSTANT which wraps the defconstant in a check that ensures that you're not trying to redefine the value with an incompatible value. That way you can define string constants without getting compiler errors.
12:16:56
TMA
madrik: you can use interned symbol instead of the string: (defconstant +filename+ '|file.name|) ; it does not feel right though
12:18:41
pjb
madrik: the purpose of defconstant is to allow some compiler optimization. Namely; defconstant tells the compiler that it can use immediate addressing for the micro-instructions using the value.
12:19:26
pjb
madrik: for a symbol, the compiler can generate an absolute addressing mode, that will be filled by the linker when the image is loaded. This works, because symbols are interned and have identity.
12:20:54
madrik
pjb: In case of a string, then, it would be best to wrap a macro around DEFCONSTANT, as loke explains?
12:22:22
pjb
So defvar doesn't assign the variable if it is already bound. It's good for program parameters, where you would set the variable before loading the program. The defvar form would give a default value, in case it's not already bound.
12:22:41
pjb
On the other hand, defparameter always assign the variable. So it's better for global variables of the program.
12:22:52
pjb
Notice of defvar is good for program parameters, and defparameter is good for program values.
12:23:30
pjb
In short: use defparameter, unless you don't want the variable to be reset when you reload the program.
12:25:15
pjb
There's a programming saying: "variables won't, constants aren't. Which means that variable won't vary, (because you should be writing functional code, so you won't modify the value of your variabels). And that constant are not constant, because you will want to change their value when the environment or the platform changes.
12:26:33
pjb
The only case you may use a global variable, is for debugging purposes, when you want to store an internal data there, so you may access it easily when debugging.
12:29:04
madrik
pjb: Does not Lisp -- Common Lisp, especially -- sport multiple paradigms besides the functional? Should one not use the others -- imperative and OO, etc. -- as fits the design?
12:29:40
pjb
This is why while you should not use global variables, there's the possibility to define them and to use them if you know better than me.
12:30:35
pjb
Also, defvar and defparameter define special variables, ie. dynamic variables, which may be what you want for some purpose (eg. the *print-…* and *read-…* variables).
12:32:12
madrik
pjb: I'm curious. A lot of functional programming seems to emphasize recursion and mapping rather than iteration. Don't you fear you'll blow the stack? Or do you only use Lisps that make a point of handling tail-call recursion well?
12:33:52
pjb
Indeed. You can use recursion up to a limit (the maximum stack size). There are optimization such as tail-call optimization, but it cannot always be implemented (and is not always implemented in CL). In CL, unwind-protect (which hides in a lot of macros) and dynamic binding may prevent TCO.
12:34:50
schweers
I don’t know where this myth comes from that Lisps are functional languages. Even scheme is not particularly suited for functional programming.
12:34:52
pjb
Notice that the processors, and the universe, is not functional. There are a lot of objects that can only be mutated.
12:35:15
pjb
schweers: it comes from the fact that it was the first programming language where you could write recursive functions.
12:36:08
schweers
C has recursive functions too, and doesn’t get accused of being a functional programming language
12:37:02
pjb
Also, lisp was the first language having a garbage collector, where you could therefore write (f (g (h))) without leaking the memory allocated and returned by h and g.
12:37:56
pjb
You can write pf=f(pg=g(ph=h()))); free(ph); free(pg); return pf; in C. Doesn't look quite functional.
12:39:52
madrik
schweers: I suppose the other myth from that time is that Lisp is interpreted -- not implementations, but the very /language/ itself.
12:41:15
madrik
Just for fun, here's a couple of Myths that Winston and Horn state on page 6 of their book:
12:43:25
schweers
Well, Lisp gives us great power, so there is more to learn. Macros for instance. Or multimethods. But I’d argue it is easier to learn how it is done in Lisp than to badly reinvent it and be a human compiler for some lesser language.
12:43:38
madrik
On the point of expensive computers, in 1989 they wrote, "... even the fastest LISP systems running on LISP-oriented workstations cost well under a hundred thousand dollars."
12:47:00
madrik
I'll make a note of it. I've mostly learned some portion of its full capabilities from the HyperSpec and the documentation for it in the CL package in Emacs.
12:52:12
schweers
Why do most languages (Lisp included) not have any facilities to automatically release any non-memory resource? I know that this can be tricky, as a GC does not guarantee when an object will be released. But honestly, I often don’t care for when it will be released, only that it will be in the not-too-far future.
12:52:36
madrik
This talk of books calls to my mind another question: when you read a good book, like /Introduction to Algorithms/ by Cormen et al, or any other book whose examples are in a different language, do you try to translate into Lisp, or do you go with the flow of the book?
12:53:34
schweers
I know, but that really is not that flexible. It’s fine when one can create an object at the same dynamic context in which it will be released, but this is not always the case or convienient.
12:55:08
pjb
schweers: and other languages with a garbage collector have finalizers, and some CL implementation have them too.
12:55:48
schweers
hmm, does java have them? Anyway, not every CL implementation seems to have them, so I guess I can’t really use them.
12:55:50
pjb
schweers: but the problem of course, is WHEN you release non-memory resources. This is the difference between memory and non-memory resources: it doesn't matter when you release the memory.
12:56:40
pjb
So if you use finalizer to release external resources, you may be unhappy, because the memory doesn't fill fast enough so the garbage collector is not called.
12:57:25
pjb
There's also another problem, when you take several resources: you may have rules on the order of relasing them. Finalizers can be called in any order.
12:58:26
schweers
I know, but this is not really an issue for me (at least I think so). While I do have resources which must be released in a certain order, those can always be put together into a struct or class
13:10:37
beach
madrik: It is almost fine. You are violating a rule that it cited on page 13 of the LUV slides.
13:13:51
beach
I often do (loop with eof = (list nil) ... until (eq line eof)), but only when the thing being read can be NIL, like when I use READ rather than READ-LINE.
13:16:13
madrik
In these situations, if an end-of-file value besides nil is used, would that value be freshly made on each loop iteration? Or is it reused, once made?
13:19:29
madrik
beach: Ah, I see. Macroexpanding the code shows that eof is let-bound before the loop proper. Okay.
13:21:14
shka_
wheter the value returned from the read-line function is the same is the same instance as the one constructed in with clause
14:11:16
pjb
Some would say that (loop for line = (read-line stream nil nil) while line) is idiomatic. Personally, I don't have problem eliding the explicit test for NIL in lisp. However, in C I started to test explicitely for NULL when testing pointers, because 0 as a symbol representing the null pointer is true only in some context. Notably, and horribly, when as argument to a function, 0 is not interpreted as the null pointer, but as an in
14:13:27
pjb
For example, CL:AND and CL:OR are very explicitely defined to return the first or last values of the argument expressions. So using (or var :default) or (and (predicatep foo) foo) are perfectly readable, just as: (loop while line) is.
14:16:58
beach
pjb: That's one leap you just made. Essentially, you are saying that anything that is semantically well defined by the language is readable to the maintainer.
14:18:06
TMA
I even use '\0' in comparisons because of the intent is more apparent (and while '\0' is equivalent to 0 in C, it is not in C++); the same goes in lisp: make the intent apparent, preferably without needless reference to something external
15:43:37
beach
My guess is that the first C compiler was not terribly smart, so you had to write code like that to get the best performance. That changed with GCC.
15:49:12
madrik
Maybe it's just looking to the past, but I get a kick out of thinking that there used to be implementations of other languages besides Lisp on the Lisp machines.
15:50:41
dlowe
I've wondered if it'd be possible to do FFI in sbcl by providing a libc implementation that used underlying sbcl code, so that allocated memory would be gc'd as usual
15:51:45
dlowe
as far as I know, all the CL implementations keep non-CL code in its own little space
16:03:18
pjb
schweers: well, since char are upgraded to int when passed as parameter and in other places it's essentially the same.
16:04:37
pjb
The difference would be '\0'+'\1' = (char)1 instead of 0+'\1' = (int)1, but againm since (char)1 would be upgraded, I don't remember any circumstance where it would make a difference. (but there may still be one obscur case).
16:07:06
pjb
(let ((s #(1 2 3 4)) (d #(1 2 3 0)) (i 0) (j 0)) (loop :while (= (prog1 (aref s i) (incf i)) (prog1 (aref d j) (incf j)))) (list i j)) #| --> (4 4) |#
16:08:23
pjb
(let ((s #(1 2 3 0)) (d (vector 0 0 0 0)) (i 0)) (loop :while (prog1 (plusp (setf (aref d i) (aref s i))) (incf i))) d) #| --> #(1 2 3 0) |#
16:09:04
pjb
(let ((s #(1 2 3 0)) (d (vector 0 0 0 0)) (i 0) (j 0)) (loop :while (prog1 (plusp (setf (aref d i) (aref s j))) (incf i) (incf j))) d) #| --> #(1 2 3 0) |#
19:16:31
phoe
I have two trees of CLOS instances that form a cyclic graph. How can I compare them for equality? For slot values that are not standard instances, I'd like to use EQUAL; for slot values that are standard instances, I want to recurse while marking the instances I have already visited to avoid loops.
19:16:53
phoe
These instances are of different types; I also want to ensure that the respective instances are of the same type.
19:18:16
pjb
If you have associations that have a multiplicity more than 1, then there could be an abiguity, and you might need backtracking.
19:18:58
pjb
Otherwise, you will need a walk of the two graphs. You can keep the nodes that are already walked in a hash-table.
19:20:11
phoe
All instances have some sort of ID however, so I can sort them by that ID in each list and then assume that the order is the same.
19:20:48
phoe
Or, whenever I traverse one graph, I get the ID of the current instance, find the matching instance in the other graph, and use that instance for comparing the slot values.
19:20:51
pjb
Then you will have to backtrack. If you have a->nb and A->nB and a=A, then you will have to try n*(n-1) b=B.
19:21:27
phoe
Will I have to, if they are ordered? I can treat these collections as ordered, meaning that 1st element of one collection must be equal to 1st element of the other collection.
19:22:24
pjb
phoe: well, that depends if the two graph share the same nodes, or only nodes that are equal?
19:23:17
pjb
Ok. Then yes, you can have a subalgorithm to match the list of nodes in the same association.
19:24:55
pjb
There were a couple of math libraries developed in Japan. Perhaps they had something about graph, I'm not sure.
20:01:25
Xach
Josh_2: (asdf:load-asd "/path/to/file") I think. Although I note that I just tried that on a bogus pathname and it returned something, so I don't know what to expect any more.
20:31:32
pjb
phoe: actually if you have a graph that knows its list of nodes, we don't need to walk the graph, just process the list of nodes (and we have to). On the other hand, if the graph is connected, and we only have one "root" node, then we need to walk it.
21:39:18
fiddlerwoaroof
You should be able to do something like (let ((buf (make-string 10))) (read-sequence buf socket-stream) buf)
22:43:59
pillton
schweers: (loop for var = (allocate-lots-of-resources) do ...) is enough to trigger problems if you rely on finalizers.