« first day (4441 days earlier)      last day (405 days later) » 

5:08 PM
Why is there a phone with a 280*653 screen
what aspect ratio...
That's what, 3:7?
 
@RydwolfPrograms Isn't panic! basically like throw?
 
No, you can't catch it in any way
The closest equivalent to throw is return Err(...), or the ? syntax sugar for Results
 
You can catch it sort of
you can assign a global panic handler that can potentially recover your program
Though it's mostly used to log the error better
 
And catching a panic in order to keep doing stuff kinda defeats the point
 
Not really
You are basically returning to a known safe point
Some types of programs are not allowed to crash in any circomstance
 
5:19 PM
But a panic often means something is wrong outside the program
 
...no
why do you think that?
 
...because every reachable panic in code I've ever written is for things like errors accessing I/O or filesystem stuff?
 
> The panic! macro is used to construct errors that represent a bug that has been detected in your program. With panic! you provide a message that describes the bug and the language then constructs an error with that message, reports it, and propagates it for you.
 
@RydwolfPrograms That's just one of many uses of panic
 
> This macro is the perfect way to assert conditions in example code and in tests. panic! is closely tied with the unwrap method of both Option and Result enums. Both implementations call panic! when they are set to None or Err variants.
 
5:21 PM
But most IO operators just return results
 
Panics should exclusively be used for things that are unrecoverable; bugs in the program itself or something weird going on outside the program that makes it unsafe to continue
 
It's your program that panics, not the IO operation. If you panic on something you know is failable it's your mistake
Panics should only happen in case of bugs in your code
 
It's not a mistake if I panic in a situation that should be unreachable
 
Yes
But a IO operation failing is always reachable
 
Like if an operation on a file or something is supposed to be guaranteed to do one thing
 
5:22 PM
so you shouldn't panic in that case
 
No, but what if the IO operation returns an error it's not supposed to be capable of returning
 
A operation on a file is always failable so you shouldn't panic
 
That's "unreachable" given your knowledge of the outside world
 
@RydwolfPrograms That's a bug in your program, or a library
All IO operations that can fail are well specified in how they can fail
 
@mousetail Not necessarily..._why_ could it fail? If the answer is "something is seriously broken and I could be about to cause some serious harm", you should panic
 
5:23 PM
No
 
You should return Err(...)
 
On Windows, some operations on stdin cause EISDIR
even though stdin isn't a directory to my knowledge
 
@mousetail Return it...to what?
At some point you have to make a decision to either ignore it or panic
 
Parent function?
 
5:24 PM
Yeah
What does the parent function do?
 
You should never panic in properly working code
 
@mousetail at some point you reach main and then what
 
Print the error and exit
If you really can't real with it
 
is that not what panic! is?
 
5:25 PM
@mousetail That's what a panic is
Reimplementing panic is just a way to cause problems
 
I guess but you shouldn't do it execpt at the very top level of your program
in which case it's equivolent to not panicking
 
@mousetail And?
Nobody's talking about whether you should only panic here or there
 
Yes you are
you said you should panic when a IO operation failed
that's not a good place to panic
since it's entirely predictable
 
That is not what I said
If you can safely recover from a failed IO operation, you should do that
You should panic when you cannot safely recover; when the IO failure or whatever indicates something is broken or damage could be done by continuing to run
or when the outside world does something inconsistent with what your program is designed to deal with, such as returning an error code you didn't think was possible
 
Yea but that's good because panic handlers will revert to a safe state, closing files etc.
That's their purpose
 
5:27 PM
The safest state to revert to is dying
Then the outside can decide to restart you if needed or possible
 
Sometimes, but for many types of programs crashing is not acceptable and you need to continue at all times
Close any invalid IO connections and recreate them
Outside = your panic handler
It's the final failsafe, in case you missed a panic somewhere
 
I guess it depends on your priorities. I think it's generally accepted that it's better for something to drop what it's doing and stop working if you "missed a panic" and come across it, rather than keep running, but idk
 
It depends on the program
 
Can you give an example of where you'd want a panic handler that restarts things?
 
A server
Yes systemctl can restart it but it will take a few seconds, you can prevent downtime by restarting yourself
 
5:31 PM
'cause for the examples of truly mission-critical software I can think of (nuclear reactor control, flight systems, etc.), you wouldn't want to just restart it, you'd fall back to some other system
@mousetail I'd rather have the downtime
 
Why? What's the risk?
 
The risk is that my service just works poorly and inconsistently for months before I realize it's broken
 
If you literally just clear any mutable program state
 
If you're panicking, the mutable program state is not the issue
 
What is?
 
5:33 PM
It's like if your washing machine catches on fire so you try using a different detergent
@mousetail The immutable state. The program itself. Or outside state.
 
Can you give a example of a situation you would panic and couldn't recover even if you cleared the entire stack
 
Any issues with mutable state should just be results.
 
@mousetail If the code has any bugs?
 
99% of panics are just dividing by 0
 
[citation needed]
 
5:34 PM
And if you're unexpectedly dividing by zero, you've got a big issue
 
And libraries using .unwrap() outside your control
 
@mousetail I hit an unreacahable state in my program, I get an error from the outside world that says "nothing makes sense", etc.
A panic is for situations where there is no clear path forward
 
That indicates a bug in your code
 
Where the program itself or the thing running it cannot be trusted
 
Restarting should get back to a valid state
 
5:34 PM
@mousetail Yes, that is what panics are primarily for
 
most of the ones I've seen have been one of: a) using unwrap wrong, b) incorrect array indices, c) EXC_BAD_ACCESS which is super annoying to debug
 
All of those are recoverable with a panic handler that loads a new blank state
 
How?
How can you recover from your program being literally broken by doing stuff within the broken program
 
EXC_BAD_ACCESS means you're trying to call or goto an address you aren't allowed to. Restarting the program won't fix that
 
When you can't trust yourself, you can't trust yourself to fix yourself
 
5:35 PM
They indicate a bug in the program. A user has performed some kind of unexpected combination of actions triggering a invalid state. So you load a valid state. Chances are whatever happened will never again
Log some info to debug later
 
And who's to say you won't just busy loop and insta-panic as soon as you try to restart
 
> Chances are whatever happened will never again
 
You can check for that
 
I disagree on this point
 
^
And again, often the issue is state external to the program
You can't fix that by changing the program's mutable state
 
5:36 PM
Like I respect your opinions but this is normally how it's done. I'm not making this up
 
Most of the time it's persistent due to a bug in the program and/or unexpected data coming from a service (e.g. the SQL database)
 
"Normally" by whom?
 
Rocket for example, the most popular rust server library
 
Eww...a library with a panic handler?
 
You can't let the server crash because one endpoint has a bug
@RydwolfPrograms You can disable it if you like
 
5:38 PM
Okay that's actually a sensible use case; "untrusted" code/isolating panics to one part of a program which is basically independent from the rest
 
Unless you carefully vet every library most panics will be trivial bugs not terrible unrecoverable memory corruption at the very base of the stack. I've in fact never seen the second in Rust.
 
Most of my experience is with frontend and not backend, admittedly
 
Ideally libraries would never panic
And I think Rust's docs specifically say they should leave it to the caller
 
Ideally, yes
 
Sounds like the solution to that problem is just to use better libraries
 
5:41 PM
Unfortunately many highly popular libraries, and ones commonly required by others, have just a few panics in very rare situations
 
I am just reminded of the entire mess that is the JS ecosystem that results in packages like is-even
 
@Bbrk24 Please tell me this is a joke o_o
 
Maybe I should make a ìs-even package for rust (that panics for 0)
 
It has a quarter-million downloads a week, there's no way it's a joke
 
var isOdd = require('is-odd');

module.exports = function isEven(i) {
  return !isOdd(i);
};
 
5:47 PM
If you go down the dependency tree a bit you find is-number with 75 million weekly downloads
which is somehow on major version 7???
 
I mean I guess that makes a bit more sense, given the weirdness that is JS's type system
 
module.exports = function(num) {
  if (typeof num === 'number') {
    return num - num === 0;
  }
  if (typeof num === 'string' && num.trim() !== '') {
    return Number.isFinite ? Number.isFinite(+num) : isFinite(+num);
  }
  return false;
};
Seriously
If you know what the type of the data is (you should) this is less than a line of code to do manually
IMO any packages that unironically list this as a dependency should be purged from NPM
 
Well HTMLInputElement#value is typed as string | number iirc
This should be completely inexcusable in node but the DOM's weirdness makes it necessary sometimes
 
@DLosc ...i thought this was a joke
wtf
Okay wow...who even wrote isOdd
It uses isNumber
Except it uses it after a Math.abs
 
@RydwolfPrograms Well, it is a joke ;P
 
5:54 PM
Which would already have cast it to a number
So it's literally just an NaN check
Which is taken care of by the Number.isInteger following it
The author is literally pulling in their own dependency for no reason other than to boost its stats I'm guessing
Either that or, surprise surprise, the guy making a library to check if a number is odd doesn't actually know that much
Also IIRC no number exceeding the max safe integer can be odd
 
To be fair, I imagine some weird JS code is weird because it was written 10 years ago as a workaround for missing features that have since been added to modern JS. That probably doesn't excuse everything, tho.
 
So that's two useless checks
ooh
And the % 2 can only be 1 if the number is an integer and not NaN
...so every single fucking line in that isOdd function is useless except the return (n % 2) === 1. Truly unmatched brilliance.
 
If isEven were the base it'd be a different story: '' % 2 is 0
 
Yeah but there's a Math.abs
before every one of the checks
 
Math.abs('') is 0
 
5:58 PM
yeah
 
wait even before isNumber? :facepalm:
 
Yep
Like I said
Truly. Unmatched. Brilliance.
We stand in the footsteps of giants my friends.
 
@RydwolfPrograms Sounds like we better move or we're likely to get stepped on
 
The creator actually seems like a cool guy tho. I think the blame's mostly on all the serious projects that actually use these useless libs
It seems like his goal was to help beginner devs more than anything
What surprises me is how this is even a timesaver for people
Like...googling for and then installing and then importing a library is way more time consuming than even C+Ving from SO, right?
 
Plus when you use a library you have to make sure the licenses are compatible
 
6:03 PM
Nobody actually does that do they
Especially not the people who'd use isOdd
 
npm bork a few weeks ago bc of a trivial library getting nuked
 
Everyone just puts a license on their code 'cause they see other people doing it, or GH asks for one, or they want to look cool
 
@Seggan One that, might I add, is built into modern JS
 
@Seggan Ooh again? Which one?
 
or do you not mean left-pad
 
6:04 PM
@Bbrk24 Worth noting padStart didn't really exist at the time left-pad was popular, and that it handled some edge cases differently
 
@RydwolfPrograms yes, left-pad
 
Leftpad was years ago wasn't it
 
@RydwolfPrograms Yeah but it did by the time left-pad was taken down
 
@RydwolfPrograms was it? i had the impression it was recent
 
> In March 2016, npm attracted press attention after a package called left-pad , which many popular JavaScript packages depended on, was unpublished as the result of a naming dispute between Azer Koçulu, a self-taught software engineer, and Kik.
 
6:05 PM
no, the story just keeps cycling because the problems it highlighted never went away
 
@RydwolfPrograms ah
nvm then
what does it do anyway
 
Pads a string on its left side
 
...
 
We have String#padStart for that now
 
thats literally a single loop and a single line of code within that loop
 
6:06 PM
it's 11 lines of code total, yes
 
yeah but it's not inline, you need to mutate stuff
Still inexcusable as a standalone library but at least it's something you'd typically split out into its own function
 
Am I weird for using CoffeeScript in 2023?
 
@RydwolfPrograms 4 lines of code, at most
@Bbrk24 yes
 
Yeah, but if it makes you happy, go for it
 
It solves the specific problems I had, and other transpile-to-JS languages didn't (e.g. TS made the problems worse)
 
6:09 PM
string = old.clone()
for (i = string.length(); i < padlength; i++) {
string = padChar + string;
}
assuming no offbyone errors
@Bbrk24 what problems
 
Well padChar can be a whole string
 
@Bbrk24 but thats the programmers job to ensure its one char
esp if this is going in the middle of a function
 
No that's a feature. Like you could intentionally pad a string to start with =-=-=-...
@Seggan A couple things. First, my scoping got all messed up, so someone in the dev console could inadvertently break stdout/stderr
(Speaking from experience)
 
I remember seeing a rather infuriating presentation/talk about the leftpad incident on YT where thr guy was like "and leftpad wasn't even that good, look, I reimplemented it better!" and showed a side-by-side feature comparison and every single thing he'd changed made it worse 💀
 
@Bbrk24 ah
still
 
6:13 PM
Secondly, TypeScript really doesn't like it if you do this:
var buffer = null, index = 0

function stdin() {
  if (index === 0) buffer = // ...
  return buffer.at(index++)
}
I considered Dart, but unlike TS and CoffeeScript, the Dart transpiler isn't available on npm
Also, CoffeeScript's distaste for punctuation makes the code way shorter. I was honestly surprised
 
@Bbrk24 yes, rescript > coffeescript
 
As in,
Original JS: 7kB
Minified JS: 3kB
Idiomatic CoffeeScript: 4kB
@ASCII-only I also needed something that didn't complain if I say "This variable already exists, I know I'm not importing it in this file, but it gets prepended by a processing step, don't worry about it." Anything with a type system makes that difficult
 
uhhhh
rescript has great support for external variables because that's kinda how it's intended to be used
so does typescript
since both are intended to be used with external JS libraries
 
0
A: Sandbox for Proposed Challenges

Huỳnh Trần KhanhAll the Boards code-golf kolmogorov-complexity Hello. We have these two shapes: #. ## and .# ## Let's call the first shape the L and the second shape the flipped L. On a 4x4 board, there are 16 cells. Each cell can be either free or occupied. In all the illustrations, # represents an occupied c...

 
@ASCII-only Rescript errors if I just give it Module["noExitRuntime"] = true, saying that Module can't be found. I need something that doesn't complain if I assume variables exist, because of my particular use-case
I'm also using proxies in a way that TypeScript has difficulty with
const elements = new Proxy({}, {
  get(target, p) {
    if (typeof p == 'string' && !(p in target))
      target[p] = document.getElementById(p.replace(/[A-Z]/g, s => '-' + s.toLowerCase()));
    return target[p];
  }
});
 
6:27 PM
 
Okay, but I don't want HTMLElement | null, I want that one to be HTMLButtonElement, and this other one to be HTMLTextAreaElement, and this other one to be HTMLDivElement, and...
or else it complains that the properties I'm accessing don't exist
So I end up plopping a massive type signature on the proxy
 
How do I get rid of that export {}? This isn't an es module, it'll be inserted into a web worker script by a later processing step
 
@Bbrk24 if you want a lack of type safety that bad you can just do Record<string, any>
 
At one point I tried typescript but with // @ts-check instead of using the tsc command. Here's the JSDoc comment that I needed to satisfy it:
/**
 * @type {{
 *  input: HTMLTextAreaElement,
 *  output: HTMLPreElement,
 *  error: HTMLParagraphElement,
 *  program: HTMLTextAreaElement,
 *  urlOutBox: HTMLDivElement,
 *  urlOut: HTMLCodeElement,
 *  copyAlert: HTMLSpanElement,
 *  urlButton: HTMLButtonElement,
 *  programFieldset: HTMLFieldSetElement,
 *  clearContainer: HTMLDivElement,
 *  footer: HTMLElement,
 *  outputLabel: HTMLDivElement,
 *  runStopButton: HTMLButtonElement,
 *  disassembleButton: HTMLButtonElement,
 *  expandButton: HTMLButtonElement,
@ASCII-only Yeah but then autocomplete hints go away
 
6:35 PM
Why not do as HTMLBlahElement where necessary?
 
@Bbrk24 pretty sure it's not generated by default. not sure why it generates it on the playground
@Bbrk24 well, you either need to explicitly specify the type, or get no autocomplete
@emanresuA and/or avoiding proxies entirely... normally i just alias document.getElementById to $...
(okay, technically i alias document.querySelector instead)
 
TypeScript is fine for node, but the DOM has inconsistencies that TS struggles too much with ime
The DOM is the reason functions are bivariant instead of contravariant in their argument type
 
uhhhhhhhhh
functions are contravariant in their argument type.
 
if you set a certain setting then mostly yeah, but for methods it depends on which syntax you use
 
methods are bivariant but that is because of people abusing classes not because of dom.
if you don't set said "certain setting" you're not really using typescript
 
6:40 PM
> During development of this feature, we discovered a large number of inherently unsafe class hierarchies, including some in the DOM. Because of this, the setting only applies to functions written in function syntax, not to those in method syntax:
 
the setting being off by default is more or less because of backwards compatibility
@Bbrk24 note how it says "including some in the DOM" as a side note
 
You either get "TS is a superset of JS" as they like to advertise, or you get strict:true by default. You can't have both.
 
how does TS stop being a superset with strict: true?
i mean, if "is a superset" means "no errors" then uhh...
@Bbrk24 which is the bare minimum required to have types at all for your elements
 
the example I gave above where buffer defaults to null instead of empty buffer
 
@Bbrk24 buffer: Buffer | null
 
6:42 PM
Then it complains that I can't call .at() on null
 
?.at()
@Bbrk24 this is, correctly, a type error
 
Except that I know that it'll never be a typeerror at runtime. Just because it can't statically prove it'll never error doesn't mean it will
 
except this would be a type error in any statically typed language
 
!.at() then
 
and again, it's trivially solvable by doing = Buffer.from('') instead of = null
or even let buffer!: Buffer = null...
 
6:44 PM
I think running into this sort of issue is a sign you should change the approach you're taking
If you know the buffer won't be null at runtime, use a way of storing the nullable buffer and index that ensures this is the case in a way the type checker can understand
 
That sounds like my experience using/learning Haskell
 
@RydwolfPrograms yeah 100%, a lot of errors JS users run into when switching from TS stem from the JS they write being very highly dynamic... and just not being statically analyzable
at all, by any language
 
I've run into this a lot with Rust where I go in with one approach in mind and try to force it to work, instead of taking two steps back and looking at it from a different perspective
 
oh speaking of alternative approaches
buffer ??= would work wonderfully too
 
Except that the processing step only understands ES2018 and some ES2019/ES2020, and so not the ?. and ?? operators
 
6:48 PM
||= would work just as well...
 
That's even less widely-supported (by browsers) than ??= actually
 
and as mentioned above, ?. is one of many, many options
= buffer || is also an option...
and if even that is not supported
there is always the trusty old if (buffer == null)
 
Does TypeScript not transpile ??=/||=
 
CoffeeScript's ? operator compiles down to a type check no matter what, it doesn't even try to use new syntax
@RydwolfPrograms It can but not by default iirc
 
@RydwolfPrograms if you set target low enough? certainly
it still has ES3 support until like, late 2024
 
6:49 PM
If you set the target too low then it clobbers [...str].length, which actually gives a different result than str.length
 
Huh, interesting. Sounds like a bug
Does it do that for performance reasons or what?
 
Because if you set the target low it assumes the ... operator doesn't exist, iirc
 
yeah ... is what, ES6?
 
Yeah but I mean, why doesn't it use the right iterator for strings
When transpiling away the ...
 
Because that iterator didn't exist in ES3/5
 
6:51 PM
Yeah but it's not hard to implement from scratch right?
You just have to check for surrogates or whatever
 
('🎈').length > [...'🎈'].length. I suppose it's not impossible to implement but they just haven't done so
 
yeah and IMO that's a major bug
it'll also affect for ... of and Array.from right?
 
yes
well at least the former, idk about the latter
 
TS should definitely use the right Symbol.iterator when transpiling away iterators
 
@Bbrk24 downlevelIteration moment
 
6:54 PM
No this is the intended behavior in plain ES6
 
The iterator over strings breaks them down into chars, whereas .length is in UTF-16 codepoints
 
@Bbrk24 yes, and downlevelIteration is the flag that uses the correct behavior...
fun fact: the flag description even says why it's not the default behavior
 
Oh so they have done it correctly. I forgot about __read
 
6:56 PM
> Emit more compliant, but verbose and less performant JavaScript for iteration.
 
Here's a thing with TypeScript: If one browser requires you to call a function, but other browsers don't have that function at all, JS lets you check typeof thatFunc. TS complains that it doesn't know that function
In one larger TS project, I have
// @ts-expect-error There's a reason that ?. is there
someObj.someMethod?.(arg) ?? true
 

« first day (4441 days earlier)      last day (405 days later) »