oh, oh wow
-
the hardest bugs to find are the ones that are direct consequences of intended behavior

okay so the current hierarchy of things is that the top-level word is
quit, which loops and callsinterpret, which callsword, which callskeyin its own loop, which callsmain-input-bufferto get the metadata pointer and passes that tokey-from. -
okay so the current hierarchy of things is that the top-level word is
quit, which loops and callsinterpret, which callsword, which callskeyin its own loop, which callsmain-input-bufferto get the metadata pointer and passes that tokey-from.so we want to split the behavior of
key-fromintopeek-fromandconsume-fromand have `key-from simplified to just call thoseand then we probably, as backfill, want to also implement
peekandconsumewhich callmain-input-bufferand invoke the*-fromvariants on it. we won't use those variants inwordbut user code might want to -
so we want to split the behavior of
key-fromintopeek-fromandconsume-fromand have `key-from simplified to just call thoseand then we probably, as backfill, want to also implement
peekandconsumewhich callmain-input-bufferand invoke the*-fromvariants on it. we won't use those variants inwordbut user code might want tothe responsibilities that
keyhave now are to check what input is present; to invoke a system call to read more if needed; to put the next byte of it on the value stack as a return value; and to advance the input buffer so that the same input won't be returned next time.so the simple way to do this would be to delegate those first three things to
peekand the last one toconsume -
the responsibilities that
keyhave now are to check what input is present; to invoke a system call to read more if needed; to put the next byte of it on the value stack as a return value; and to advance the input buffer so that the same input won't be returned next time.so the simple way to do this would be to delegate those first three things to
peekand the last one toconsumehowever we're realizing that this also bears on one of the big compatibility questions we've had in mind from the start, which is how to make sure it's not too annoying to deal with situations where the temporal behavior of input matters
-
however we're realizing that this also bears on one of the big compatibility questions we've had in mind from the start, which is how to make sure it's not too annoying to deal with situations where the temporal behavior of input matters
that's been a big frustration of ours in Rust (though it's been better since the Rust library
smolcame along, it was quite frustrating with several popular async libraries prior to that point)a stream isn't just a sequence of bytes, it's a sequence of bytes that arrive at some point in time and possibly in response to things happening in the world outside of the program
-
that's been a big frustration of ours in Rust (though it's been better since the Rust library
smolcame along, it was quite frustrating with several popular async libraries prior to that point)a stream isn't just a sequence of bytes, it's a sequence of bytes that arrive at some point in time and possibly in response to things happening in the world outside of the program
sometimes you care about the difference between "the next available byte" and "the next byte available right now"
-
sometimes you care about the difference between "the next available byte" and "the next byte available right now"
and we're just trying to make sure we don't paint ourselves into a corner with how we organize this functionality
-
and we're just trying to make sure we don't paint ourselves into a corner with how we organize this functionality
we don't need to add anything to deal with temporal behavior right this moment, but we want to make sure it's clear how we would
-
we don't need to add anything to deal with temporal behavior right this moment, but we want to make sure it's clear how we would
so the thing we're calling
peek, notionally, includes the responsibility of waiting, as part of that system call(see? you thought we were being overly pedantic in listing all that, above! admit it :D)
-
so the thing we're calling
peek, notionally, includes the responsibility of waiting, as part of that system call(see? you thought we were being overly pedantic in listing all that, above! admit it :D)
we disapprove of global mutable state, so whenever we do add a non-waiting variant, it would be a separate call with a separate name, not a flag we toggle
-
we disapprove of global mutable state, so whenever we do add a non-waiting variant, it would be a separate call with a separate name, not a flag we toggle
(at the kernel level, it's an
ioctl()that you do on the file descriptor, which persistently changes its behavior, but we can still organize our tooling to hide that fact, if we want, and we do)notionally it could have the same responsibilities but in a non-waiting version
or we could break the responsibilities down into even more granular pieces. hm hmmm. these are deep questions
-
(at the kernel level, it's an
ioctl()that you do on the file descriptor, which persistently changes its behavior, but we can still organize our tooling to hide that fact, if we want, and we do)notionally it could have the same responsibilities but in a non-waiting version
or we could break the responsibilities down into even more granular pieces. hm hmmm. these are deep questions
"peek" is already a really nice word for "look to see what's there but carefully don't change anything"
it's not immediately obvious what word we would use for "be even more careful than peeking, just make it really quick"
oh - "glimpse" lol... if we want to run with the visual metaphor. maybe we do.
-
"peek" is already a really nice word for "look to see what's there but carefully don't change anything"
it's not immediately obvious what word we would use for "be even more careful than peeking, just make it really quick"
oh - "glimpse" lol... if we want to run with the visual metaphor. maybe we do.
okay. fine. we aren't deciding on "glimpse" now, we just wanted to know there's at least one reasonable way forward before we proceed with "peek". there is, so we're going to proceed. yay

-
okay. fine. we aren't deciding on "glimpse" now, we just wanted to know there's at least one reasonable way forward before we proceed with "peek". there is, so we're going to proceed. yay

keeping these big-picture concerns in mind can be tedious
-
keeping these big-picture concerns in mind can be tedious
hmmmm okay, so, we think we'll have
consumedo nothing if the buffer is already empty -
hmmmm okay, so, we think we'll have
consumedo nothing if the buffer is already emptywe could make it silently corrupt internal data structures in that case, but that feels pointlessly cruel to our future selves

-
(at the kernel level, it's an
ioctl()that you do on the file descriptor, which persistently changes its behavior, but we can still organize our tooling to hide that fact, if we want, and we do)notionally it could have the same responsibilities but in a non-waiting version
or we could break the responsibilities down into even more granular pieces. hm hmmm. these are deep questions
@ireneista preadv2, pwritev2, send, recv, sendmsg, recvmsg, and the like all have ways to avoid blocking.
-
R relay@relay.infosec.exchange shared this topic
-
we could make it silently corrupt internal data structures in that case, but that feels pointlessly cruel to our future selves

@ireneista Isnβt the complete lack of type checking in Forth already cruel?

-
@ireneista Isnβt the complete lack of type checking in Forth already cruel?

@alwayscurious it's for sure a thing we're going to change

-
@alwayscurious it's for sure a thing we're going to change

@ireneista Static or dynamic?