freenode/#lisp - IRC Chatlog
Search
17:15:14
phoe
nonetheless, type detection in some Lisp implementations (including the most popular ones) works decently, which is why you get that type warning during compilation.
17:18:43
pjb
adlaistevenson: the point is that the lisp systems validate the correctness at run-time, because it can change at run-time!
17:19:18
pjb
adlaistevenson: when you write an AI that learns, and compiles new knowledge into itself at run-time, you cannot prove it ages before.
17:21:02
pjb
adlaistevenson: furthermore, there is indeed the important question of what you call correctness: all lisp data is valid and correct lisp program (well almost, you can declare safety 0 and get a bunch of undefined behavior). But otherwise, you should always have controlled ie. "correct" execution, at the most basic level.
17:21:47
pjb
adlaistevenson: there can be an incorrect program, ie. a bug, only if you have a specification to check the behavior of the program against. To let do that by the computer, you will need a FORMAL specification.
17:23:14
pjb
It correctly signals a program-error (or an error, depending whether you pass it to the compiler or the interpreter).
17:23:41
Bike
checking that an algorithm implements a function isn't NP-hard. why would it be NP-hard? it's impossible. but for specific cases it's reasonable.
17:24:21
phoe
Bike: "when you write an AI that learns, and compiles new knowledge into itself at run-time, you cannot prove it ages before."
17:26:00
pjb
Often even multiple times the expected lifespan of all the universes in the multiverse.
17:28:16
Bike
whatever. lisp question. what happens if you use a forward-referenced-class as your metaclass.
17:29:37
pjb
If the metaclass cannot be finalized, there's no way to use it to even create a non-finalized class, so nothing can help.
17:30:52
Bike
actually, wait, to be a metaclass it has to be finalized, so the defclass with the :metaclass should finalize it at compile time (or if that's impossible, signal an error)
17:48:59
drmeister
If I break up a job across 8 threads and set them all in motion - does it make sense to have a loop that does JOIN-THREAD on all of them to synchronize with them all?
17:50:33
drmeister
(let ((threads (loop for x in jobs collect (make-thread #'(lambda (job) (do-job job))))) (loop for x in threads do (join-thread x)))
17:55:02
pjb
Granted, it may be needed more often in threads to collect the result, but honestly if you use threads, it's probably because the problem is more parallel than sequential, so you don't have a single result at the end in general, but you will have computed vectors of results during the processing.
17:55:43
pjb
drmeister: we fork more often than we wait for children, because synchronization with the termination of children is rarely needed.
17:56:46
pjb
In case of threads, often they will mutate a common data structure, so the final result is already synchronized around those mutation, and we don't care when it's complete.
17:57:07
pjb
My point is that it make sense to use join-thread, but also not to use it, when you don't need to.
17:57:55
drmeister
In this case I need to aggregate all of the results together. But I think now I'll use a thread pool and farm off smaller jobs to them. I have about 300 C++ source files that need to be analyzed to identify pointers in classes within the code. They can be analyzed in parallel - but the results need to be aggregated to generate code for a garbage collector.
17:59:01
pjb
drmeister: yes, if you keep worker pools, and initiate tasks by messaging them, you will get the results thru some messaging, and not at the end of the thread (they will be infinite loops). In this pattern, you don't need join-thread (it'd block forever).
18:01:44
drmeister
Hmm, I just incorporated a non-locking multi-producer, multi-consumer queue - I could use those here.
18:03:11
scymtym
drmeister: it make this kind architecture quite easy. e.g. https://lparallel.org/pmap-family/
19:25:41
Bike
I thought sb-alien took care of that, but I guess not. If you use CFFI instead, it should do en/decoding transparently, as far as I remember.
19:28:20
kefin
inotify_event has some uint32 and at the end a char*, but it doesn't write to what that ptr points to, it writes essentially "past" the struct object, and the char ptr represents that
1:46:58
krwq
is there any tree-equal equivalent which works with both vectors and lists? (but #(1 2 3) != (list 1 2 3))
2:20:14
krwq
ok, so i don't see why there is atom function at all, i could as well (not (consp ...))
2:22:04
White_Flame
but basically, there's not a super clear line to draw the distinction, so there's no built-in
2:26:04
krwq
thanks for explaining this, I thought that the atoms were stuff like character, integer, string (soft ground) etc but nothing more complex
2:33:02
pjb
krwq: notice that atoms are not atomic either. It was tought originally they were atomic, and then we discovered electrons and nucleons. And then we discovered quarks. And then we imagine there are strings.
2:34:44
pjb
White_Flame: (let ((p #c(1 2))) (complex (real-part p) 3)) vs. (let ((p (make-point :x 1 :y 2))) (setf (point-y p) 3) p)
2:55:43
Zhivago
It's important to understand that atoms are essentially syntactic elements in lisp, rather than data types.
3:35:09
whoman
Zhivago, they cannot be divided further, in the sense. but what is there to consider aside from s-exps? if atoms build the structure, when are they not meaningful that is?
3:46:53
Zhivago
Atoms form part of the structure of s-exps. They're not meaningful when you're not talking about s-exps.
3:47:33
Zhivago
e.g. '(a b c) might be an s-exp (in which case, talking about atoms is meaningful) or it might just be a list of three symbols (in which case, talking about atoms is not meaningful)
4:09:31
ricky_ricardo
So an expression can't return an expression? Is that right? (just learning at the moment)
4:10:03
ricky_ricardo
Is it correct for me to say that a macro is similar to an expression, but it can return expressions?
4:10:44
White_Flame
a macro itself only differs from a function in that its parameters come in raw & unevaluated, in their source code form\
4:11:13
White_Flame
other than that, they work exactly the same as functions, returning data which should be in the form of source code to evaluate
4:11:55
White_Flame
a macro can return the _list_ (+ 1 2 3), containing 4 elements (one symbol, 3 numbers)
4:21:57
beach
ricky_ricardo: An expression can not return an expression, simply because "expression" in Common Lisp means data made up of atoms and CONS cells, so they can not return anything. Only functions (including macro functions) can return things.
4:21:59
beach
Now, technically, since a function is an atom and an expression can contain any atom, it is possibly for that particular kind of expression to return something when it is called, but that is not typically how the term "expression" is used.
4:24:08
marvin2
if you passed quoted sexps to a function, which returned a sexps (that is passed to eval after the call), is there any practical difference between that and a macro?
4:25:19
beach
marvin2: One difference is that a macro function takes an environment object that can be used to macroexpand sub-expressions.
4:26:32
Zhivago
ricky: You can think of that as how a macro is essentially implemented -- the remainder being protocols on when that gets applied.
4:33:00
jasom
vtomole: garbage collection, compiler, allows function-redefinition (with some restrictions).
4:34:07
vtomole
Of course, im just trying to figure out how it is implemented on a Lisp that is bootstrapped. I'm not sure how to phrase my question...
4:35:04
beach
vtomole: By "a Lisp that is bootstrapped", so you mean that it is written in some other language?
4:35:16
jasom
vtomole: I can think of two lisps in which the GC was implemented entirely in its self, and neither of them are common lisps
4:35:52
beach
vtomole: Ah, then you "just" have to generate machine code that does all the things that the system needs.
4:37:30
vtomole
jasom: Mezzano's runtime is all lisp: https://github.com/froggey/Mezzano/tree/master/runtime
4:37:58
jasom
https://github.com/froggey/Mezzano/blob/master/runtime/runtime-x86-64.lisp <-- it's a stretch to call that lisp
4:38:12
Zhivago
libc is part of a C implementation -- if it's part of the runtime depends on implementation choices.
4:38:55
Zhivago
vtomole: Sure -- and this is part of why longjmp doesn't guarantee to free up VLAs, for example.
4:40:53
Zhivago
There are things that need to be done -- organizing i/o, memory management, dynamic linkage, etc, which are generally considered to be part of the run-time of a system. If you're using a different definition, you probably need to talk about it.
4:42:05
jasom
glibc does in fact implement much of the C runtime; other parts are (possibly) intrinsic to the compiler (e.g. alloca())
4:42:54
whoman
we can write C that doesnt link to libc, cant we? runtime would add extra code. well any library is a runtime then
4:42:54
jasom
just don't type-pun without unions or have signed integer overflow (both of which you can do bare metal on most archs)
4:43:27
jasom
whoman: and I can write lisp code that doesn't ever CONS, so doesn't need at least the GC part of the runtime...
4:44:16
whoman
well lisp is kinda executed at runtime so it needs something before any code, i think i would call that a runtime
4:44:37
jasom
whoman: what about all the C code that runs before main (clear the BSS, initialize the heap, &c.)
4:45:21
Zhivago
There is nothing fundamentally different between C and lisp run-times, except for the protocols required (e.g., GC vs malloc, class-of, etc).
4:48:07
whoman
C's malloc could be avoided, though. you can write your own in your C code. i think C's runtime is minimal tiny boot header to find main and dlink stuff to preload dynamic libs
4:48:08
Zhivago
Sure, and I'll point out that they're still not portable. How do you portably implement FILE, for example?
4:48:28
Zhivago
C's malloc cannot be portably avoided unless you want to limit yourself to auto storage.
4:49:01
whoman
even in objective-c i wrote my own and almost didnt need the built in runtime (which the standard libs require)
4:49:11
jasom
Zhivago: gtk and qt are both called "portable" but they acheive that by implementing code specifically for different targets
4:50:05
Zhivago
jasom: You're confusing gtk being portable, with things that depend on gtk being portable.
4:51:24
Zhivago
And C has runtime for longjmp, and handling floating point error modes, and i/o, and memory management, and character locale support, and ...
4:51:45
whoman
ok- "whatever parts of the development system required for executing what is developed with that system" - runtime. lisp needs the whole image then, it is the runtime. ok i understand now
4:51:59
Zhivago
There's really no fundamental difference, except in terms of which interfaces they provide with which semantics.
4:52:22
Zhivago
lisp needs nothing more than what lisp needs, just like C needs nothing more than what C needs.
4:52:44
Zhivago
In lisp, (class-of x) needs to work -- how it works can vary -- it may need no run-time support at all.
4:53:10
jasom
whoman: there are many lisp implementations that can create images without parts of the runtime (e.g. the compiler) to make smaller images
4:54:08
whoman
well now we got the word 'implementation' - for eg. GNU C compiler, one can swap out the c library. what do we call an implementation of C
4:54:52
whoman
jasom, but the images is the development environment, like needing a web browser to execute html.
4:55:06
Zhivago
Whatever you swap it out with will need to be tailored specifically to work as part of gcc.
4:55:58
jasom
whoman: sbcl creates a base image that is loaded; you could swap it out with any compatible image just as you can swab glibc for musl
4:56:17
whoman
Zhivago, yeah the C code swapped of course should work as a valid replacement part =)
4:56:17
jasom
the fact that nobody has written such an image is orthogonal to the fact that it is technically possible
4:57:09
jasom
whoman: it's not even just GCC code, it's GCC code with a particular ABI (32-bit PowerPC had 3 different calling conventions in use on different OSes at one point)
4:57:34
whoman
Zhivago, but we can swap the library with other compilers after a produced binary of course. the compiler isnt needed
4:57:40
Zhivago
Probably the biggest issue for CL is that it lacks a declarative program definition.
4:57:48
jasom
whoman: the lisp runtime is much larger than the C runtime, *and* it is much more tightly coupled with the compiler due to garbage collection.
4:58:25
jasom
whoman: so writing a new runtime for sbcl would be much harder and less useful at the same time.
4:58:48
whoman
well, i think lisp *is* the runtime. and i think that C has a small bootstrap. what would the smallest C binary be produced, contain? just library linking info?
5:00:28
jasom
whoman: the smallest C program would be "int main() { return 0; }"; it's an implementation-detail how much runtime is needed to execute that
5:00:36
Zhivago
No. The C compiler realizes an implementation of a C program that is runnable on a target machine.
5:03:11
White_Flame
there's mechanism to call main, take its return value and pass it back to the OS. However, as has been mentioned above, that could conceivably be inlined with the bootstrap and collapse down to never actually entering a "C runtime environment"
5:03:16
whoman
well, this is what i think: for C compiled without optimizations, a simple return 0 in asm is likely produced. lets say we can produce the same unoptimized program from a pascal compiler without runtime. the binaries would be the same or not?
5:03:49
Zhivago
If hand compiled by the same person, why not? They're the same program, after all ...
5:05:10
whoman
i grew up with C, just trying to establish my beliefs about it since i havent really challenged them before (thank you) ^_^
5:05:31
jasom
pascal on 16-bit x86 traditionally ordered the function arguments in the opposite order from C on the stack
5:05:42
whoman
White_Flame, aha true. because reduced to functions, unoptimized, any compiler is just asm dialect then.
5:08:13
jasom
whoman: the C standard is very different from C implementations, sometimes surprisingly so. Furthermore C implementations tend to try very hard to be compatible with whichever C implementation was used to compile the operating-system libraries (for obvious reasons), so multiple C compilers on the same OS happen to be compatible; this isn't required though.
5:08:17
White_Flame
again, for tiny degenerate cases, where there's provably no other callers, the conventions can be ignored
5:08:38
jasom
e.g. the word "memory" does not appear anywhere in normative parts of the C99 specification.
5:09:30
White_Flame
since no in-language mechanism sets that up, it's the runtime that establishes that before any function is called
5:09:39
White_Flame
however, a runtime can also unload itself by the time the userspace code actually runs
5:10:16
jasom
whoman: no, it just changed READ, which is a library function, not part of the runtime :P
5:11:02
whoman
i mean at expansion time sorry =) that is, adds a level of language scope for every macro level. if that makes sense.
5:11:25
White_Flame
unless you specifically meant that "*c* function-calling needs to run-time at all"
5:11:55
jasom
whoman: but if you run a tree-shaker, it's possible that your runtime won't even include the function READ.
5:12:07
Zhivago
white_flame: What I mean is that there does not fundamentally need to be run-time support for function calls in C (or any other language).
5:12:40
whoman
hmm. implementation level can be different all the time. forth does its own stack doesnt it? it can be written in C. C could also be written in forth or whatever. just levels of implementations i think , i cant find the line between one and another now
5:12:46
Zhivago
Although there does need to be run-time support for constructing function calls in CL for programs which use that.
5:13:24
White_Flame
the program counter doesn't enter any runtime utility during a function call/return mechanism itself, right
5:13:30
whoman
jasom, unless it is referenced in the code which the tree shaker shook ? why would it shake out used things. lets imagine no shaking!
5:14:05
White_Flame
well, I can think of one language where the runtime is invoked for function calls: forth
5:14:19
jasom
whoman: just mentioned that as a parallel to "C that isn't linked with libc"; teasing out the runtime from the standard-library is ill-defined