freenode/#lisp - IRC Chatlog
Search
5:01:47
beach
jasom: Are you referring to a real debugger (where you can set breakpoints, step by form, trace, examine data, etc), or what we habitually call a debugger but that really isn't?
5:03:17
beach
jasom: And I have a specification for one of the former type, but it will require support from the implementation that most implementations may not have yet.
5:10:02
beach
If you don't want to have a slot writer (which often happens to me), then you can use REINITIALIZE-INSTANCE instead.
5:10:23
beach
I mean, you call REINITIALIZE-INSTANCE inside the :AFTER method on INITIALIZE-INSTANCE.
5:13:39
beach
It has nothing to do with CLOS. It is the same in every language. Slots (or fields, or data members) are implementation details that may change in the future.
5:13:46
krwq
beach: I think I'll pass with this for now, slot-value works - I'll likely get to that point where I understand the advantage
5:14:03
beach
Accessors are part of the documented protocol (or interface, as most other languages call it).
5:14:44
krwq
beach: I see - this is meant to be implementation detail, I do not want any accessor here
5:15:35
beach
You typically still want an accessor. It is what is called an "internal protocol", i.e. even in your module implementation code, you want to be somewhat modular.
5:16:44
beach
Here is another reason: It is possible that in your implementation, SLOT-VALUE, (SETF SLOT-VALUE) etc. are slower than slot accessors.
5:17:22
beach
Not in SBCL though, which basically converts SLOT-VALUE with a constant slot name to a kind of slot reader.
5:18:35
krwq
beach: I might gradually get to the better design but haven't thought through the internal protocl yet
5:18:38
beach
I mean that your Common Lisp may have to do more work with slot-value, because it first has to figure out where the slot is stored in the object, given the class of the object and the name of the slot. This procedure can easily be bypassed in a slot accessor, and less easily with slot-value.
5:19:10
beach
Sure, you don't think of that in the beginning. But it is good to prepare for them by not using slot-value or with-slots.
5:19:50
beach
It's easy. Just stick a :reader or :accessor in there with a name that is not exported.
5:20:44
beach
So, stick a reader or accessor in there, use those to access the slot, or use WITH-ACCESSORS where you would otherwise use WITH-SLOTS.
5:22:41
beach
In my code, the name of the slot serves only two purposes: The primary purpose is so that when the DEFCLASS form is re-evaluated, the Common Lisp implementation knows that it is the same slot as before. The secondary purpose is so that the Common Lisp implementation knows that when a slot is mentioned in both some class and some subclass, I meant for it to be the same.
5:26:58
beach
That way, I don't have to mention slot names explicitly, and the code continues to work even when slots are added or removed.
5:27:31
krwq
beach: I had hard time with that when the library I used added some slots I didn't want with the metaclass
5:28:52
beach
That is when the pairs initarg/accessor are useful. I often use a registration mechanism so that the relevant pairs are available by a call to a generic function.
5:29:30
beach
For example, when I save an object to a file, it is saved as [<class-name> :initarg1 value1 :initarg2 value2...]
5:30:00
beach
That way, I can reload the file even after my implementation has changed, so that some slots are added or removed.
5:31:21
beach
https://github.com/robert-strandh/SICL/blob/master/Code/Cleavir/Abstract-syntax-tree/general-purpose-asts.lisp#L28
5:32:49
beach
No, it is simple. Less than 100 lines of code: https://github.com/robert-strandh/SICL/blob/master/Code/Cleavir/Input-output/io.lisp
5:35:32
beach
All I need to do in order to read an object saved that way is a reader macro on #\[ that does (apply #'make-instance (read-delimited-list ...)).
5:41:46
beach
Most of the code is there. I am working on the bootstrapping procedure. Also, Bike is working on Cleavir, and probably heisig as well pretty soon. Right now I am working on indentation in the editor.
5:43:00
beach
Well, Climacs already exists, and I am working on version 2 of it, which is planned to have much better functionality for editing Common Lisp code.
5:44:53
krwq
clim can display on everything and I assume your implementation is using clim interface
5:47:04
beach
The plan is to propose a set of tools for Common Lisp programming that are an order of magnitude better than the Emacs-based tools we have today.
5:48:04
krwq
beach: fair enough but if you've proved the point of clim universality by making it work with emacs it would gain in popularity much faster and likely gain contributors faster
5:48:54
krwq
don't want to sidetrack or anything but that sounds like a nice hackathon project or something you could give to a student
5:49:16
beach
Yes, but that is not my primary goal. My primary goal is to have a comfortable Common Lisp-based environment, and to have my effort to create it count as research.
5:50:51
krwq
good point but note that if you did it this way then you could reverse the dependencies by making emacs work with clim as well and those emacs modes could eventually work with climacs
5:52:01
beach
Yes, well, someone who is interested in working that way could do it. I'll work on what I am good at. In particular the hard parts that require fresh research.
5:53:04
beach
No, because (first) Climacs is not as good as Emacs, even for Common Lisp programming. This is why I am working on Second Climacs.
5:53:54
krwq
beach: I'll be interested to test it once it is usable and fairly convenient. I write most of my stuff in CL either way
5:57:14
smokeink
speaking of decent debugging, I've found this overly complicated https://www.youtube.com/watch?v=q_ARlVo-J5Q how come it's so difficult to access the local vars during debugging?? Is this feature really that unimportant ?
5:59:01
krwq
I'm seeing clim has a lot of potential, currently feel like some defaults look ugly but each time I try it it feels much better and things like clim-debugger are proving it
6:01:31
smokeink
you can break and display the local vars, but what if you need to interact with them? You need to play around with them, to see where they fail to behave as you were expecting..
6:02:19
smokeink
Personally I use a little trick that I've stolen from the book LetOverLambda : https://paste.ofcode.org/9ShVACskzbYG68W7X44RsT
6:02:52
beach
krwq: Yes, McCLIM is steadily improving, thanks to jackdaniel and several recent contributors. I am very happy with the way things are going.
6:04:08
beach
smokeink: It is hard, because Common Lisp implementations take advantage of the freedom the Common Lisp HyperSpec give them to optimize lexical variables.
6:05:22
beach
smokeink: Information about the location, type, etc, of lexical variables must be made available at runtime in order for a debugger to use this information. And it must be done in a way that does not hamper performance.
6:07:24
beach
For one thing, the compiler typically reduces the scope of lexical variables. They are not kept around after their last reference. So the programmer may want to examine the variable, but the compiler has eliminated it at that point.
6:08:27
beach
Suppose (g y) signals an error. The stack frame of this expression no longer contains X because it is no longer live.
6:10:31
beach
Different problem: (let ((x ...)) (declare (type fixnum x)) (f x) (g x)). Suppose (f x) signals an error. The programmer uses the debugger to alter X so that it is a string instead of a fixnum. The call to G may then fail by having your Common Lisp crash.
6:11:51
beach
The technique suggested in that video slows down the code a lot, so it is only acceptable as a temporary solution.
6:13:33
smokeink
okay: my point is maybe pandoric macros can be of help, perhaps a less cumbersome solution using pandoric macros is possible - it's an interesting thing to research
7:11:23
smokeink
krwq: (declaim (optimize (debug 3))) (let ((v1 2) (v2 3)) (incf v2) (break) ) ; krwq can you eval in frame and get v1 or v2's value?
7:15:07
krwq
yes, but I'd put (declaim (optimize (debug 3))) in your .sbclrc or whatever config file you use
7:16:28
smokeink
ok, I already had (declaim (optimize (safety 3) (debug 3) (space 0) (speed 0))) in my .sbclrc , but I can't evaluate v1 or v2 in frame... It always says they're unbound
7:39:52
pjb
Try with: (declaim (optimize (debug 3))) (let ((v1 2) (v2 3)) (incf v2) (break) (values v1 v2))
7:41:18
beach
smokeink: I think that's what I said before. The compiler eliminates variables that are not live, independently of the scope defined by the programmer.
7:42:05
beach
Suppose (g y) signals an error. The stack frame of this expression no longer contains X because it is no longer live.
7:42:35
pjb
Even if the variable was live, it could be eliminated, eg. if it is used only once, and side effect order wouldn't be changed by replacing its use by its initial expresion.
7:44:00
smokeink
it's good to know that one can add a (values v1 v2 ... ) at the end, then the (break) can be put anywhere in the let body
7:44:38
beach
smokeink: If the LET is in a context where its values are not needed, the compiler can remove those too.
7:44:48
phoe
which might be a bit overkill to work with vectors since it's meant for any-dimensional arrays
7:45:26
phoe
smokeink: in general, the compiler is free to optimize everything that doesn't affect the final outcome of the function.
7:46:27
phoe
if you want fast and optimized code, then you want the compiler to be able to optimize the hell out of it
7:46:47
phoe
if you want debuggability, you want the compiler to probably not optimize a single thing
7:47:27
beach
whoman: The compiler is obviously only allowed to perform semantics-preserving transformations.
7:48:33
TMA
whoman: semantic-preserving does not entail preserving the choices made under undefined behavior though
7:51:43
beach
phoe: Not quite that easy. It is entirely possible that the implementation decides to define behavior that is labeled as undefined in the standard. If so, it kind of promised to preserve the semantics of that behavior.
7:53:22
emaczen
pjb: is (reduce fn (mapcar (compose #'bt:join-thread (lambda (piece) (bt:make-thread ....))))) the correct form composition for map-reduce?
7:55:04
phoe
There's been a series of discussions that BT:JOIN-THREAD's return value is not meant to be used as anything meaningful, but I've yet to see a free implementation that doesn't return the thread function's return values in that case.
8:02:21
emaczen
I'm just testing out a simple map-reduce with generating a range of numbers, splitting the range into 4 equal partitions since I have 4 cores, and then evaluating. It is actually a lot slower...
8:04:49
phoe
and it's harder to screw up with LPARALLEL than it is by rolling out your own implementations.
8:06:06
emaczen
Using (time ...) the only difference I see between sequential code and my threaded map-reduce code, is that the sequential code uses 0.2% of the CPU and the threaded code uses 77% of the CPU
8:06:53
emaczen
phoe: my code is not much more complicated than that (reduce fn (map ..)) form I showed earlier
8:09:03
whoman
if you want to do it your way, why insult the vets giving you real world wisdom and making them watch you go through what they went through
8:10:33
whoman
(just curious, does it matter if the list is linked in both ways, if the map goes one way?)
8:11:31
emaczen
whoman: not sure if it is necessary but I used the previous link for programming ease
8:12:38
whoman
they can be mutated/destructed during traversal too, its cool =) just wondering if an existing map could walk it
8:16:31
emaczen
whoman: Actually I don't think it needs to be doubly-linked, however I made a mistake in lower levels of my code so I think I have to
8:21:30
whoman
i stay frozen solid unmovable due to immobilizing fear of mistakes. since when i started life... =P
8:44:32
smokeink
Let's say I have this fib function that breaks when the parameter n equals 2 , https://stackoverflow.com/questions/27889989/stepping-in-sbcl-from-within-the-debugger?rq=1 How to proceed to STEPPING , right after the (break) , without using slime's Return From Frame" (R) and manually typing (fib 2) ?
9:28:12
ludston
emaczen: doing things in parallel is pretty easy. The tricky part is the synchronization afterwards.
9:30:45
ludston
That is, if you follow a simple rule; don't ever modify state that is being referred to by more than one thread. Things like mapreduce are handy abstractions that people have invented for following this rule.
9:40:26
dim
doing things concurrently is easy when it makes sense that every one is only minding their own business, computer beings involved or not ;-)
9:42:41
ludston
Doing trickier things than that is usually a bit of a mine field for other people trying to work with your code. (Imho this is why Google based their parallelism on mapreduce-> it means that Google devs didn't have to worry about the minefield that is trying to guess which state might be modified by multiple threads the first time that they are looking at some code)
10:01:17
beach
::notify emaczen You might want to look at Amdahl's law: https://en.wikipedia.org/wiki/Amdahl%27s_law
10:38:59
smokeink
Why is sbcl's core image (27mb) so huge in comparison to Corman CL's (1.5mb) ? How is it that FreeBasic can create binaries as small as 120kb (that can portably plot gfx onto a GUI window ) ?
10:40:52
dim
compare with Go binary images maybe, or those produced by something that doesn't link/require libc at runtime
10:41:28
beach
smokeink: The Common Lisp runtime is more complex than (say) that of C, because CLOS needs the compiler and there is the garbage collector of course.
10:41:37
dim
IME most small executable binaries are small because they just rely on the right version of libc being there at runtime
10:42:11
beach
smokeink: Having said that, I think someone should create a Common Lisp implementation where most of the code is in a shared library.
10:45:25
jackdaniel
fwiw that's how ECL graphical application works on android – libecl is accessed via jni wrapper from java
10:51:58
jackdaniel
dmiles: all functions are (unless they are bytecompiled, in that case you have to use cl_funcall)
10:52:50
jackdaniel
there is a calling convention for functions with &optional, &key etc as well as for closures
10:54:12
dmiles
very nice.. (despite working on wam-cl i have quite a bit i plan being done with ECL from SWI-Prolog's new LibFFI)
10:56:52
jackdaniel
fittestbits: I have good news for you, I've fixed the ticket you reported yesterday (will push in a minute)
11:49:24
scymtym
fe[nl]ix: could you make a fiveam release? i think the accumulated changes justify one
12:02:54
scymtym
fe[nl]ix: maybe getting rid of asdf's "recursive use of test-op" before the release would be good? or immediately after the release, depending on how you operate w.r.t. these things