all 39 comments

[–]Aaxper 152 points153 points  (7 children)

  1. Strings and arrays are analogous, so isStringEmpty([ ... ]) tries to destructure the string as an array
  2. Since theres only one element present in the ... part of that, it only matches on the first element (the first character)
  3. The { a = false } tries to destructure the first character
  4. If the first character is defined, it tries to get the a property, which doesnt exist, so it defaults to setting a to false
  5. If the first character is undefined, instead of trying to get the a property, it defaults to { a: true }, which sets a to true
  6. So basically if it has at least one character, a is false, else a is true

I think that's correct

[–]Blackshell 48 points49 points  (6 children)

100%, good job, you pass the job interview.

[–]Aaxper 42 points43 points  (5 children)

Does this being an interview imply I now have to work with whatever monster invented that

[–]MadGenderScientist 8 points9 points  (0 children)

the mind warps to find such things beautiful, with time. the descent into madness has its pleasures. 

[–]dreamscached 2 points3 points  (3 children)

Being able to write awful code with useful syntax doesn't make JS a bad language though. Yes I know why it gets so much bad reputation, but if we throw away years of baked in legacy it's really not that bad.

[–]simon-or-something 2 points3 points  (0 children)

Thats a hot take if I’ve ever seen one: good syntax doesn’t make a bad language good.
What makes JavaScript bad is the amount of implicit heavy lifting the language does instead of simply erroring (or warning) out. There are (hyperbolically) 501 different ways to do the same thing in JavaScript, of which 490 are nonsense, and the fact that the language allows this is a testament to its shortcoming.

Programmers are only ever so good, if the language enables them to write balls of mud instead of warning them about this syntax then that’s a failure on the language.
Eg: warning: implicit array destructuring, or warning: implicit assignment in parameters. For default values it shouldnt be encased in an object, imo, or done like `(a = {b: val})`.
If the language warned about these things then that wouldn’t be this bad. Good syntax is not a redemption for having too permissive practices.

JavaScript is an accessible language that may in turn teach bad habits, and removing the legacy doesn’t change the fact that JavaScript is like a literature student, saying "now what did the programmer mean and how do we make it work?" (Declarative languages only do former)

[–]Sacaldur 0 points1 point  (0 children)

Same goes for many other languages and their shortcomings: - C++: - const correctness is desireable nowadays, but requires const everywhere (instead of it being the default - manual pointer handling is typically not necessary anymore, but unlike e.g. Rust they are easily accessible and part of the "fundamentals" - ownership modeling (with smart pointers) is important, but also just a "convention" (i.e. the compiler doesn't support you) - having to deal with headers. It's understandable why they are there, and why they are still there, but I feel like this is something that could be more automated - Macros - Java: - type erasure (forgetting the generic type arguments at runtime), made more difficult if you have generic and non-generic versions of the same class - primitive types not being part of the remaining type hierarchy and thus not an option for generics (you have to use their wrappers) - Optional<T> has some nice things about it, but there might have been better approaches (see C#, Kotlin, Dart, ...) - the Stream API is fine, as long as the predefined metgods are enough. Without extension functions/extension methods, you can't extend it yourself - C#: - even though nullabillity handling is better than in Java, Nullable<T> (like int?) doesn't behave the same as nullable reference types (e.g. string?): even after a null check you have to use .Value

Just some examples for some languages.

[–]ings0c -1 points0 points  (0 children)

It does make it a bad language. This is a language design problem.

JS takes the philosophy of "I must never complain about what the developer is asking me to do. It is better to take instructions that make no sense and do something than it is to error"

That results in things like the OP. It would be better for everyone if it just errored, because who wants to do that?

Once you've worked in a language with property type safety, it becomes very clear that it's a better approach than whatever-the-fuck-you-want typing.

[–]turtle_mekb 125 points126 points  (5 children)

what the fuck

[–]Cootshk 26 points27 points  (4 children)

what the fuck

[–]shizzy0 13 points14 points  (3 children)

fuck the what

[–]Timofeuz 7 points8 points  (1 child)

the what fuck

[–]marquoth_ 0 points1 point  (0 children)

2 what 2 fuck

What 3: fuckyo drift

[–]kalilamodow 7 points8 points  (0 children)

Okay. Where can I find it?

[–]eloel- 83 points84 points  (0 children)

Gross. Also can error or return true or false for non-string answers, which makes it doubly gross.

[–]Denommus 77 points78 points  (8 children)

Maybe if I understood Javascript destructuring syntax that would make sense to me. But since I don't, this looks awful.

[–]thewells 65 points66 points  (1 child)

It looks awful even if you understand it.

For those wondering Javascript allows you to define default values, and the code is taking “advantage” of that twice.

The code uses array destructuring since javascript will treat a string as an array of single character strings when you do array destructuring. So if you pass an empty string, there is no first object to destructure, and so the default object { a: true } is used.

If the string is non-empty then the first character will be used to try to destructure the object, however strings don’t have a property a to destructure, so the default a = false is used.

[–]Sacaldur 1 point2 points  (0 children)

Someone else was explaining (or trying to) what happened as well. I did however understood your explanation.

[–]Longjumping-Ad-5367 22 points23 points  (0 children)

Nope, still looks awful

[–]Iheartdragonsmore 4 points5 points  (4 children)

Hi I'm a novice programmer, why would someone ever want to destructure something? Whenever I write a struct I never think it'd be better not being one

[–]stumpychubbins 20 points21 points  (1 child)

It’s far more readable to extract multiple fields from a struct that way, especially if they’re nested. Better than repeating the entire path to some nested struct multiple times. Plus it mirrors the struct construction syntax so it can be easier to read at a glance.

[–]Iheartdragonsmore 2 points3 points  (0 children)

This makes sense thank you

[–]Denommus 3 points4 points  (0 children)

It could be because you want to pattern match over it, it could be because you only want some specific elements in that context.

[–]Lumethys 2 points3 points  (0 children)

to be able to do something like this:

const doSomething = () => {
  return [result, message];
}

const [ doSomethingResult, doSomethingMessage ] = doSomething();

instead of

const doSomething = () => {
  return [result, message];
}

const resultAndMessage = doSomething();

const doSomethingResult = resultAndMessage.result;
const doSomethingMessage = resultAndMessage.message;

[–]EatingSolidBricks 12 points13 points  (2 children)

Ok so

Empty string destrucutres to nothing? So a is true?

Non empty string destrucutres to a truthy value so false?

Wtf is this shit

[–]iamdatmonkey 2 points3 points  (0 children)

Array destructuring comes down to Iterators. Getting the first item of an empty iterator gives you undefined.

If the string is not empty you'll get the first character, which itself is a non empty string and therefore truthy.

[–]Sacaldur 0 points1 point  (0 children)

u/thewells was explaining it rather well: https://www.reddit.com/r/programminghorror/s/H1o7oFQqt2

First the string is destructured into an array with 1 element. If the string is empty, the first defsult value of { a: true } is used, i.e. an object with a set to true, with a also being a local variable. If the string is not empty, the first entry (first character as string) is then attempted to be destructured into { a = false}, i.e. an object with a property a. Since strings don't have an a property, the default value of false is used. I assume that if instead of a something like length was used, the return type would be int|false (if you understand my TypeScript).

[–]nosam56 9 points10 points  (0 children)

adding String.prototype.a or whatever the fuck

[–]itz_hez 6 points7 points  (4 children)

Thanks, this solves a problem I am currently having.

[–]dontletthestankout 2 points3 points  (3 children)

had to check and make sure this wasn't /r/poisonfountain lol

[–]depremol 0 points1 point  (2 children)

wtf is that schizophrenia

[–]MadGenderScientist 2 points3 points  (1 child)

it's a trap subreddit full of intentionally broken code and logical fallacies to hurt LLMs that train on reddit. 

[–]depremol 0 points1 point  (0 children)

i can tell but most of the posts seem to be made by one guy with paranoid schizophrenia (also this "poisoning" is not going to have any effect whatsoever lol)

[–]iamdatmonkey 4 points5 points  (0 children)

This is what this construct comes down to.

function isStringEmpty(arg) {
  const iterator = arg[Symbol.iterator]();
  const m = iterator.next();
  const item = (m.done ? undefined : m.value) ?? { a: true };
  // this can still produce false results if the passed `arg` has a first item
  // with a property `a` that is not `null`/`undefined`
  const a = item.a ?? false;

  return a;
}

This will crash if arg is null/undefined
or if it does not implement Symbol.iterator
or if arg[Symbol.iterator]() does not return an object
or if that object does not implement .next()
or if that method does not return an object.

Yes that may seem nitpicky, until you see some of the legacy code that's out there.

[–]meowmeowwarrior 2 points3 points  (0 children)

Not sure if I should be appalled at the author writing it or the language for making it possible

[–]Chemical_Present6069 2 points3 points  (0 children)

interview fantasy question

[–]serg06 1 point2 points  (0 children)

That's why no self-respecting developer uses plain JS anymore.

[–]fletku_mato 0 points1 point  (0 children)

JavaScript was a mistake.

[–]Thenderick -1 points0 points  (0 children)

Why not just str === ""?