freenode/#sbcl - IRC Chatlog
Search
18:20:31
stassats
is there a rationally for poorly implementing our own mutexes and condition variables?
18:22:51
jsnell
I would have guessed it was another of those cases of system calls actually working properly on OS X
18:24:34
nyef
stassats: IIRC, the memory requirement for futexes is a single (unboxed?) word, plus possibly kernel memory overhead /while they are being slept on/.
18:26:42
nyef
So no foreign objects to track that can leak, for example. A winapi mutex is represented by a HANDLE, but it's tied to some kernel state that can leak.
18:30:41
jsnell
I'm trying to remember whether that special support was anything except custom finalizer machinery. probably not
19:28:28
stassats
i'd be fine with that, as i'm fine with using dispatch_semaphore in slime, but something available to a wider audience would be preferable
19:31:22
stassats
i still think any normal program shouldn't create and discard too many mutexes, so finalizers should do
19:58:05
fortitude
is it normal for a thread in gc_stop_the_world to have GC_INHIBIT and IN_WITHOUT_GCING set? relatedly, shouldn't gc_start_the_world set IN_WITHOUT_GCING to NIL, or a stored value?
20:32:42
foom2
Google open sourced the C++ Mutex implementation we use internally. It doesn't use pthread mutex, instead using some sort of per-thread waiter or something like that.
20:33:02
stassats
we could even detect that a function is only using a hash-table to call gethash/puthash and not lock it
20:34:15
stassats
foom2: the current sb-thread:grab-mutex works everywhere too, but it doesn't unscheduled itself and has to spin instead
20:35:46
stassats
i still imagine a proper pthread_mutex can use better techniques than just sleeping
20:35:58
foom2
https://github.com/abseil/abseil-cpp/blob/master/absl/synchronization/internal/waiter.cc
20:40:57
foom2
But in any case, the possibly-heavyweight platform-specific stuff is only used to implement blocking, and so there's only one per thread.
0:09:54
White_Flame
hopefully a dumb question, but since sb-ext:run-program's :environment accepts a new environment list, does that mean it entirely replaces all envvars? How do you get the current complete envvar list in order to pass all existing envvars plus some additions?
0:34:52
White_Flame
now I just have to figure out why python is ignoring my PYTHONPATH, but that's for another place
0:40:36
White_Flame
I think I'll have to break down and register a nick with freenode. the demanded registration idiocy of all the other larger programming channels is getting unbearable
0:41:41
pfdietz
In SBCL, (upgraded-complex-part-type 'integer) == RATIONAL. In CLISP, it is INTEGER.
0:43:11
pfdietz
"(complex type-specifier) refers to all complexes that can result from giving numbers of type type-specifier to the function complex, plus all other complexes of the same specialized representation."
0:43:44
stassats
and that it should satisfy (typep realpart 'type-specifier) (typep imagpart 'type-specifier)
0:45:29
pfdietz
(complex integer) is the same as (complex #.(upgraded-complex-part-type integer)), by that quote.
0:47:04
pfdietz
(upgraded-complex-part-type 'rational) = RATIONAL, so complexes formed by giving rationals have the same specialized represention. So, the "plus all other" part of that sentence means they're included too.
0:48:55
pfdietz
"This type encompasses those complexes that can result by giving numbers of type typespec to complex."
0:51:57
pfdietz
If INTEGER and RATIONAL both have their own specialized representations, then #C(1 1) should not be in (COMPLEX RATIONAL), even though 1 is a RATIONAL. It can't be in both. So I take this to mean "upgrade to the most specialized representation that works and use that."
0:53:31
pfdietz
typep does say this: "(typep object '(complex type-specifier)) returns true for all complex numbers that can result from giving numbers of type type-specifier to the function complex, plus all other complex numbers of the same specialized representation."
0:55:04
pfdietz
I vaguely recall this became a point of contention when I was putting together ANSI-TESTS, so perhaps it's best to just document what interpretation SBCL will be using and move on.
1:01:35
pfdietz
nyef: you specify the element type of arrays explicitly when you make them. Complex does it automatically, and exactly how that's supposed to work is the issue.
1:03:13
pfdietz
CLISP does have the problem that #C(1 1.0) is a complex, mixing integer and float. That contradicts the spec.
1:03:29
stassats
should've said "returns true for all complex numbers that can result from giving numbers of type (upgraded-complex-part-type type-specifier) to the function complex"
1:05:55
pfdietz
Ah, I see what I was forgetting. Unlike in arrays, if A is a subtypep of B, then (complex A) is a subtype of (complex B), even if they have different specialized representations.
1:17:56
stassats
'(upgraded-complex-part-type 'T1) and (upgraded-complex-part-type 'T2) return two different type specifiers that always refer to the same sets of objects'
1:18:21
stassats
how can two different type specifiers refer to the same objects? why is upgraded-complex-part-type different then?
1:19:34
nyef
Aren't BIT, (UNSIGNED-BYTE 1), (MOD 2), and (INTEGER 0 1) different type specifiers that refer to the same objects?
1:23:11
pfdietz
He's just illustrating that different type specifiers can denote the same set of objects.
1:25:21
pfdietz
By the definition of subtypep, if T1 and T2 denote the same set of objects then (if subtypep can determine their relationships) then each must be a subtypep of the other.
1:25:59
Bike
it says "T1 is a subtype of T2, or [etc]" so the etc covers the case where rather T2 is a strict subtype of T1, i.e. they upgrade to the same thing. right?
1:26:06
nyef
That "if subtypep can determine their relationships" might be important, but is unlikely to be in this case.
1:26:51
pfdietz
The only reason this is not totally clear is because of the contradiction on the page for TYPEP.
1:27:52
pfdietz
Where it asserts that (typep x (complex foo)) ==> (typep (realpart x) foo) and (typep (imagpart x) foo).
1:31:57
stassats
pfdietz: but given the set of all floats, it'll never give a complex number with the REAL upgraded
1:33:03
pfdietz
(complex float) doesn't mean precisely those things generated by calling the function COMPLEX on floats.
1:34:33
stassats
if you have (complex float), and upgraded-complex-part-type is REAL, then (typep #c(1 2) '(complex float)) should be true?
1:34:58
nyef
Oh, wow. The definition of subtypep doesn't constrain T1 or T2 in the array subtype case, therefore it claims that (array 42) is a type specifier.
1:35:55
pfdietz
Complexes are not like arrays. (array bit) and (array t) are disjoint, but (complex rational) is a subtype of (complex real) even if they are not identical.
1:36:59
stassats
that's why the "(typep realpart 'type-specifier) (typep imagpart 'type-specifier)" part
1:38:00
pfdietz
I realize this is CLHS lawyering, so it would be ok to just document the issue and move on.
1:38:14
stassats
well, the other parts are bonkers, i'm choosing the parts that contradict the non-bonkers side
1:39:36
pfdietz
I don't think it is bonkers. It's straightforward. (complex X) == (complex upgraded-X). Those typep assertions are just wrong; they should be (typep (realpart x) (u-c-p-t 'typespec)) (and for imagpart).
1:40:02
nyef
The specification is internally inconsistent and the semantics are both unreasonable (in a specific, technical meaning of the term "unreasonable") and largely incompatible with modern, non-lisp praxis.
1:40:51
stassats
the alleged requirement for (typep #C(10 20) '(complex float)) to return T is the bad part
1:41:39
nyef
I don't know if (array nil) is brilliant, stupid, brilliantly stupid, or stupidly brilliant.
1:42:03
stassats
all the complexes called with (complex a-float) wouldn't result in #C(10 20), or its equal representation
1:42:04
pfdietz
I'm totally ok with the implementors deciding to interpret the spec differently than I do, but I think it should be documented (if it isn't already). Hmm, let me look at the manuak...
1:44:36
pfdietz
Strictly interpreted, the subtype relationship isn't even computable, which means the upgrade- functions aren't computable either.
1:47:41
stassats
and sbcl knows (sb-kernel:specifier-type '(complex (eql 0))) => #<SB-KERNEL:NAMED-TYPE NIL>
1:51:49
nyef
... Oh, FFS. DEFTYPE: "Recursive expansion of the type specifier returned as the expansion must terminate, including the expansion of type specifiers which are nested within the expansion."
1:52:34
Bike
deftype is pretty explicitly a macro thing, so it's not really suitable for recursive types anyway
1:54:48
Bike
no. actually i thought pkhuong or someone had a sketch of implementing recursive types in sbcl that required plenty of work
1:56:11
Bike
types are in this weird space in CL where they're supposed to be all of optimization for the compiler, predicates, classes, and storage specification (for arrays) at the same time, and it doesn't work if you go into it
1:57:20
nyef
aeth: Right, it's a SATISFIES type. That helps for type checking, but not really for anything more clever.
1:58:49
pfdietz
My beef is that I want function definition to mean "if I call it with these types, it returns these types."
2:04:02
stassats
sbcl function declarations currently use a mishmash of different ways to specify stuff
2:04:13
stassats
like (defknown identity (t) t (movable foldable flushable) :derive-type #'result-type-first-arg)
2:06:41
pfdietz
I want type specifiers that are expressive enough to drive a random input generator, like Haskell's QuickCheck.
2:06:43
Bike
and since you can also derive a type from the other arguments it's probably fine to just say fuck it and have the type be a function to compute a type
2:06:46
stassats
doesn't really matter, this stuff is not exposed to the user and handles things ok for now
2:09:59
pfdietz
Is there a GC performance win if you can determine lifetime of stuff, even if you can't stack allocate it?
2:10:03
stassats
when writing programs i want everything be relaxed and easy, but with a compiler-optimization hat on, i want everything to be strict and typed
2:10:55
stassats
pfdietz: there could be, if there's no interrupts in the meantime, the allocation pointer can be reset to the original value
2:11:57
stassats
or i've been thinking about tracking hash-table uses, if they are allocated inside the function and are only called by gethash/puthash, they can avoid locking
2:15:59
pfdietz
One would like to be able to track if they are passed to other functions, that they don't "escape".
2:17:13
stassats
the main reason i want dynamic-extent for ftype declarations is for auto stack allocating closures
2:18:59
stassats
but overall, i don't think really strict and fancy type system help solve problems any better
2:21:22
Bike
i think it's pretty funny how the CLHS has this bizarre-ass definition because they didn't want to say it meant stack allocation
2:22:39
pfdietz
It sort of means "at the end of this scope, no one else refers to this object". So would a free definition say something like "whenever X occurs, it's the only thing refering to its object"?
2:24:23
Bike
i think it says that something inaccessible except through the dx variable will still be inaccessible except through the dx variable.
2:24:31
pfdietz
This would mean you could move the object around and not care about other things pointing to it.
2:26:41
stassats
it could mean that if you have (defun foo (x) (let ((z (list x))) (declare (dynamic-extent z)) ...)) (foo (list 1)) could become stack allocated as well
2:28:03
Bike
i remember clhs says that but also that you'd have to watch out for foo being redefined (not that it matters for standard functions)
3:00:48
stassats
if upgraded-complex-part-type returns the type it's passed, will that dissolve any silliness implied by the standard?
3:04:07
loke`
stassats: Out of curiousity, as this is the first time I've ever come across UPGRADED-COMPLEX-PART-TYPE; what is the purpose of this function? I can't think of any actual use for it.
3:06:32
loke`
I'm reading the clhs on it... I'm still confused... “returns the part type of the most specialized complex number representation that can hold parts of type typespec”. That does that even mean? “parts of”? Does that mean that always returning BIT is valid?
3:07:41
stassats
"The purpose of upgraded-complex-part-type is to reveal how an implementation does its upgrading."
3:11:30
loke`
stassats: Fair enough... I thought I started to understand what it does, but then I realised that when passed 'FLOAT, it returns REAL. Why is that?
3:12:51
stassats
it could conceivably return FLOAT, since there isn't actually a REAL specialization either
3:13:45
stassats
sbcl has three representations for complexes, double-float, single-float and everything else
3:16:00
loke`
So if I care about space, I should explicitly specify complex numbers with integer parts as #c(1.0 2.0) instead of just #c(1 2)?
3:17:40
stassats
ok, single floats use less space, double floats will have the same amount as fixnums
3:21:38
stassats
so you would chose the types according to what operations you perform, not really how sbcl packs it
3:33:07
loke`
stassats: True... I I've been studying quantum mechanics recently, and I guess that's why I have come across it recently.
5:17:13
slyrus
Is it possible to get rid of (with appropriate declarations) the unable to optimize away %sap-alien notes when using sb-alien::alien-callback?