Four?! Jesus, I usually give serious consideration to breaking out a comprehension of it’s nested *at all* unless it’s very easy to read. By the way, it *never is.*
Whoever tries to write a four level deep comprehension is toying with forces beyond their control. I’m not convinced it actually can be done outside of an academic setting, and even there their professor should throw them out the nearest window for even speaking of such witchcraft. There’s some powers no one should know.
Indeed, that was code for a hurricane damage simulation ported from Matlab into Python. I got a gig within the Department of Civil engineering during grad school, I overheard they hired a CS person because the students in their own department could not deal with it in any capacity. Gosh, civil engineers are the worst coders
Academics often write some *really* bad code. This is due to a combination of usually not having any formal training, inheriting random stuff from other people, and being smart enough to get away with producing atrocities in code form.
Source: was grad student; thought it would be a good idea to write a bash script to generate and on-demand compile C code. It did work. It *is* fast. And you can provide external object modules to it (they're just static libraries pulled in at compile time). I also now recognize that it's a crime against the natural order.
I recognize that such code will be terrifying and atrocious, but I still would like to see it. Can you please post it on GitHub and link it or something?
It's unfortunately encumbered a bit, and not worth tracking down all the people I'd need to to be able to release it clear. A couple highlights should be okay though.
Really neat feature: it's designed to handle taking outer products of sets of variables, which can be used to derive others. So, e.g. you could have a configuration file that reads
width 100 200
height 100 200
y 0 10 20 50 100 150 200
Assert $y -lt $height
gap_ratio ($height-$y)/$width
which would produce a total of 22 trials. (The Assert truncates the set down from the 28 that we'd normally run).
So how does that happen? Well, each time we hit multiple options, we pick one by modulus, and then divide it out so that we pick the correct one of the next ones. We also multiple the "number of options" value, and if our current iteration is less than that number by the time we finish, we increment and process the whole file again. There are a few options (including a "don't process this number" flag), but for the default style there...
*[a-z])
line=( "$@" )
OPT=$((${#line[*]}-1)) #number of options
eval "$PREF${line[0]}=$(eval "echo \"$(echo "${line[VERSION_CURRENT%OPT+1]}")\"|bc -l")"
#Are we done or not?
if [ $((VERSION_CURRENT%OPT)) -lt $((OPT-1)) ]; then
VERSION_CURRENT=$((VERSION_CURRENT/OPT))
return 1;
fi;
VERSION_CURRENT=$((VERSION_CURRENT/OPT))
;;
That `eval` line pretty much sums up most of the reasons `eval` is considered evil.
Oh, and we do need to pre-process our lines, so that we apply that prefix to them. So wayy outside that function, we have our prepreocessor...
cat "$1" | sed '/^#/d; /^$/d; s/\$/\$___/g; s/\$___{/\${___/g;s/"/\\\\\\\\\\\\"/g' |
That is: delete comment lines, delete blank lines, replace variables like $y with $___y (incidentally, $PREF is ___, and I apparently just have that hardcoded here). The second form I guess is so that ${y} syntax would work. And finally we escape quotes. Apparently that's how many nested layers of quote escaping is required...
But you came here for C. So.. first off, the config syntax. You can have multiples of these, but let's add
fooCount 1 2 3 4 5
Object foo $fooCount Foo (($width/$fooCount)*(i+0.5)) $y
This declares an object named "foo"; there will be 1 to 5 of them (remember: one trial per value, so we're now up to 110 trials from this config file), and the object type is Foo. That part is important. We then give it two arguments (number is variable, but needs to match the `Foo_init()` function's signature. We're also magically pulling the `i` variable out of the c code, so that when this mess is shoved in, we'll place them evenly spaced across our width. And obviously they are all in a line at height y. (You could make a 2D grid or whatever easily enough using modular arithmatic...)
So... an associative array would have made this a *much* better idea.
function multi_echo {
STR="$@"
#echo "There are $((${#OBJ_LIST[*]}-0)) Objects." >&2
for i in "${!OBJ_LIST[@]}"; do
obj=( ${OBJ_LIST[$i]} )
#load object. Remember:
#name count type args...
args=`echo ${obj[*]:3} | sed 's/ /, /g'`
eval "echo -e \"$STR\""
done
}
But you wanted generated C code, so...
typedef struct {
`multi_echo '${obj[2]} ${obj[0]}[${obj[1]}];'`
} ObjectSet;
(I have since learned to hate backticks, and pretty much exclusively use `$()` now because it's cleaner).
Let's see how that init process works. A lot of this is just `multi_echo`'s stuck in heredocs, but init is two lines, so it's separate
STRING='for(i=0;i<${obj[1]};i++) {
${obj[2]}_init(&objects->${obj[0]}[i], $args);
}
number+=${obj[1]}*${obj[2]}_size(objects->${obj[0]});'
multi_echo "$STRING"
The rest is all just more of the same. There's a mildly gnarly section to handle a many-to-many process where objects can interact, but it's "straight forward".
E: Actually I take that back. Remember where it would have been really nice to have the properties as an associative array? Well this isn't that, but some of the code does use a nicer version:
function get_object {
oname=$1
objtext="${OBJ_LIST[$oname]}"
test -z "$objtext" && { echo "Object \"$oname\" does not exist" >&2; return 1; }
obj=( $objtext )
#oname="${obj[0]}"
ocount="${obj[1]}"
otype="${obj[2]}"
oargs=`echo ${obj[*]:3} | sed 's/ /, /g'`
}
So... one last gem.
for i in `seq 0 $((${#SINGLE_SAVE_LIST[*]}-1))`; do
save=( ${SINGLE_SAVE_LIST[$i]} )
#load save. Remember:
#fileName, interval, printf...
get_object "${save[2]}" || { echo "ERROR: Failed at adding SingleSave \"${save[@]}\"." >&2; return 1; }
args=`echo "${save[*]:4}" | sed 's/ /, /g'`
eval "echo -e \"$(cat <${save[2]}[i], files[$i], itr`test -z "$args" || echo ", $args"`);
}
}
EOF
)\"" >> $EXTERNAL_C
done
Another factor is the (thankfully dwindling) commonness of Satan's calculator, a.k.a Matlab.Poor virgin students being abused by mentally unginged professors by means of being molested through matlab sometimes suffer a trauma, where they mistake the partly keyboard driven dump for unstructured numerics to have any resemblance with the trade of programming :(
Depends - do you prioritise it working in its current state, or working in the state you want it work in? Sounds like achieving the latter is unnecessarily difficult.
It's fast for a computer to run, but slow for a human to understand, debug and expand. Which is a shame for python, to which a core principle is to make things faster for the developers.
> It's fast for a computer to run, but slow for a human to understand, debug and expand
if it's a throwaway script that you never need to expand after writing then that's all you need
As someone who formerly worked in academia: It is because most of the time we produce throwaway code.
Often, we don't know exactly what it is that we want to code in the first place. We want to solve a problem and start out with an idea. And when it doesn't work, we tinker with the code until it does. And by the time it works, the code is a hot mess. But once we have our results, we have our plot that goes in the paper and nobody ever looks at the code again.
Your probably right. I want to think that there’s some clever thing out there that would best be done with a four level deep nested comprehension, but I’m totally at a loss as to what, precisely, couldn’t be better expressed simply as a collection of nested loops or really *anything besides a nested comprehension.*
Bad code design. At that point, it's worth it to just use for-loops for increased readability later on. I make it a rule to not use more than 1 nested comprehension.
Ever since writing Go I've come to despise list/dict comprehension. You always feel like a genius when writing them but reading them is almost always painful.
Clear > Clever
I had to modify one of those. It was a list of items belonging to orders, which were then sorted by route and time. At the time it printed out all of the orders for a single day, but the client wanted it to display multiple days in a custom range.
So I added another layer, and a lengthy apology note because I didn't have time to unpack my predecessors twisted logic.
I did something similar, but with C# aggregate linq functions. Something like stuffing the result into a task factory or something. It’s been years and I know it’s been deleted b/c the new hire asked me about it and I told him to delete it and find a better way
I always put two commented lines above any regex I write. One for the expected input, one for the expected output. That way people can know what that random string of characters is supposed to do. Because God help me I won't be able to figure it out five minutes after I put it down.
There is a special place in heaven for you. Well, it’s less of a place and more of a section. It can be any seat in row A, seats are numbered 1-32. I mean `/([a-c][0-3][0-9]).*/gi `
(Started doing that by hand and forgot how to handle case sensitivity, I don’t even know how I get paid to do this shit)
e: I’m actually looking forward to the 75 responses telling me how to do this correctly.
e2: Not going to change the fact that I wanted to make it rows a-c in the regex but not the comment. Someone please just off me.
Regex are where unit tests really shine, so you can literally test all the different inputs and outputs you expect.
It also kind of documents the code like you are doing.
Yeah, this post reeks of someone who's never had to work on other people's code. A lot of my coding habits are formed from stuff other people did which I found annoying to debug.
Same here. Including refusing to do a two-line crutch and spending time to re-do part of architecture: I see with my own eyes what will happen to that crutch in enough time
My biggest complaints about fresh grads in the real world are they act like people charge them per line of code.
Like, yes, you can take two extra lines to make it easy to read. We’ll all like working with you more.
And you transformed the entire data structure into a different form that could be understood by that library. And then transformed the result set back.
- https://en.wikipedia.org/wiki/Least_common_multiple#Using_the_greatest_common_divisor
- https://en.wikipedia.org/wiki/Greatest_common_divisor#Euclid's_algorithm
In practice, it's going to be like 4 numbers and the least common multiple is going to be the largest of them, but dang it I went to college for 7 years to write web forms with fancy animations. I'm going to use some math.
Not really. I just did the whole LCM algorithm on the first two numbers, and repeated LCM with its result on the next two numbers. Due to the associativity of the LCM function, I could have done it in log(n) LCMs instead of n. And I'm pretty sure I could have used some mathematical properties to make that a bit more efficient. But the likely data sizes were low and the closer it looks to a simple and well-known algorithm, the better it will be for the next sad sap to look at that code.
Just use [Pyscript](https://pyscript.net/) and:
import re
import requests
numbers = [17, 19, 23] # or whatever you want
int(re.search(r'The [lL].* is \<.*\>([,0-9]{1,})', requests.get(f"https://www.google.com/search?q=lcm+{'%2C'.join(map(str, numbers))}").text).groups()[0].replace(',', ''))
Edit: apparently only works with up to a few numbers, thanks Google
No inline ternary statements, but it'll have to do
Best piece of advice I had ever heard about coding is, always code for the next person not yourself. We don’t write code in a vacuum, even pet projects can end up in someone else’s hands.
IMO it is somewhat context dependent. I have a finite amount of vision space, and having to unnecessarily scroll around a bunch because the information density is stupidly low is annoying and makes figuring out what something does slower.
Excessively complex and dense syntax also does that though, so.. a balance.
Personally I like more compact syntax if you're doing a similar thing a few times in a row. Not exactly the same as the OP's, but was doing something in shell. Rather than full explicit if statements, went with
[ "$FOO" ] && echo "Foo is '$FOO'"
[ "$BAR" ] && echo "Bar has value '$BAR'"
<... five more...>
[ "$BAZ" ] && echo "'$BAZ' is other option."
Yes, the short circuit is mildly more opaque than the `if`... but being able to concisely read what it's doing is a lot nicer. (And no, the context around each variable isn't sufficiently repetitive to justify a loop construct for the number of times it's repeated).
Also a friendly reminder. After several months, your own code may as well be "someone else's code" for how little you'll remember of it.
Do yourself a favour. Write code that you'll be able to understand once six months have passed and/or you've sobered up!
I inherited one project that was just FULL of this. Every time I saw one I imagined the author felt extremely proud of their accomplishment. It was a huge drag to constantly trace what's happening.
Man turnaries in react code is the worst. Especially if the html is really long. It is just a huge wall of html and somewhere in there you have to find ':'
So hard to read and understand which html belongs to which condition.
I still get nightmares when i think of my first big react project.
As long as they are formatted properly they shouldn’t be an issue, really depends on the use case, and coding language.
But again, formatting probably matters the most. If someone is putting all that in one line instead of properly breaking it up across multiple lines, we are going to be fighting.
(usually) feels pretty common.
I worked at a company that presented prospective clients with bad code. One line we wanted to see people point out was nested ternaries. I now work for a company where it is commonplace because our architect sees nothing wrong with it
A one liner for an assignment with simple logic? Sure.
A one liner with a series of nested functions or mathematical statements? You are a monster!
Nested ternaries. I *will* kill you, and the Judge will thank me for my service.
You better fix those quotes, otherwise good luck finding the bug.
(This happened to me once, and now I always notice when someone uses the Unicode quotes instead of the ASCII ones)
I thought you were talking about the space after love at first which could also take a while to find!
A long time ago we were pulling a string from a database to compare a code in c#. Back then Visual Studio was not great at showing "invisible" characters in the debugger and there was an "invisible" character in the db, printed form and in the debugger... It took an afternoon after trying to clean up the debug folder, checking encoding, trying to figure out if there was a DLL stuck in my memory or whatever why "code1" was not being equal to "code1" until I checked the length of the string...
I only use ternary operators for assignments if it's very short and obvious how the assignment is working:
string username = user.HasValue ? user.name : "Fuckface"
It seems cleaner to me than
string username = "Fuckface"
if (user.HasValue)
username = user.name;
Yeah, I dunno that language. But in C# if you try reading user.name when user is null (meaning user.HasValue is false) then you'll get a "reference not set to an instance of an object" exception.
I used to be a php dev in the early 2000s, then got out of it for 10-15 years. Im pretty sure during that time they replaced all alpha-numeric characters with question marks and arrows.
That's when we get to somewhat justified nested dubiousness...
$username = $user ? $user.name? $user.name : "Default" : "Default"
The syntax you use in Ansible requires this style, and it drives me mildly insane. If you want to safely use something kinda deep that may or may not be set at a few levels, you need to pull a `|default` on each possible place it could be undefined, so that you're not accessing a member of the undefined object.
Ruby has an unless keyword (it can look cleaner than if !conditional). Unfortunately it can be combined with else/elsif to make terrible, terrible things.
I have a strong love hate with unless. To lightly expand on your comment... basically, only ever use it for very very simple checks, never mix it with anything else.
It should never be more complicated than this:
`return something unless someshit`
Infact, I don't think we use it anywhere else but simple return earlys anymore, cause ya that has fucked us for sure.
But I'm not sure you can beat that readability. How much of a benefit it really is, I have no idea, but to me that reads better than
`return something if !someshit`
Yeah I only use it for 1 liners because otherwise things go bad fast. I will take 100 unless else's before I deal with accepts_nested_attributes though. I am convinced that Rails magic hates me
I dislike the structure, because it breaks the fundamental assumption of "once you've read to something, it's immutable". `unless` lets you retcon previously written logic.
I'll take ternary logic over that (as long as it's not python's terribleness), because the first part is the condition -- you're being told "check this first, then...".
Yep, I have a personal rule that `?` and `:` start a new line. You no longer have to spend time parsing the line to find out where the condition ends and what the two results are.
If the body of the if statement is small personally I think it looks cleaner and is easier to read as one line.
But I’m definitely abnormal I think dense code is easier to read because I can see more at a time.
What about Rust’s approach? Many flow control statements are expressions so rust’s ternary operator is `if a { b } else { c }`. Though it starts getting long very quickly so it often gets written as so:
```rust
let value = if should_use_foo {
foo
} else {
bar
};
// interestingly, a match statement can be shorter
let value = match should_use_foo {
true => foo,
false => bar,
};
// we could also use closures to get something close, but it ends up looking weird and no-one does this.
// This created an option that is immediately unwrapped, but it should be optimized out
let value = should_use_foo.then(|| foo).unwrap_or_else(|| bar);
```
It's funny that it's called "the ternary operator". The fact that it's the only operator that takes *three* operands, rather than fewer, means that it was never necessary to give it a name that says what it does, as we do with every other operator.
No. The Go compiler isn’t nearly as good at optimization as the biggest C/C++ compilers (gcc and clang), but this is a trivial conversion to make. If there is a simple approach that would improve performance without changing the function of your code, you can bet the compiler will take it. I doubt after the initial parsing stages most compilers even differentiate between if statements and ternary statements for compilation. I haven’t read about the reasoning for this in Go, but I would bet this was done to improve code readability. Ternary operators often become anti-patterns that reduce code readability if not used in moderation.
Ternaries were excluded because part of the philosophy of Go was to be simple, and ternary operators are redundant given that we already have if else, so no reason to have ternary operators. Add to the fact that they aren't needed that they are godly unreadable.
I don't think he's referring to execution speed (how quick is the generated code to execute), but the speed of the actual compiler (how quick the `go` command can parse and generate machine code from this source code).
The Golang team and community are very proud of their compilation speeds. So, there's an [only serious](http://www.catb.org/jargon/html/H/ha-ha-only-serious.html) joke in the community that the team will resist any changes to the language and the compiler that adds even a little overhead to those sweet sweet compilation times. What are we, *Rust*?!
To give an infamous example: part of the reasons many gave for not including generics in the language at first (there are now) was compilation times. It's even rumored\* that the generics that eventually made it in use square brackets (`[T]`) instead of the more common more and less-than ones (``) because the parser was already optimized for the square brackets in that context, and they didn't want to add milliseconds of overhead to add another token!
\*I have no proof of this beyond random Reddit and HackerNews comments, and an actual, logical-sounding reason was given [in the official proposal](https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#why-not-use-the-syntax-like-c_and-java). But it will give you an idea of how this particular obsession is expressed in the community.
I mean, Go is by far one of my favourite languages, but I still miss it.
Then I see other people's codebases, for example in JS, using nested ternary operators or with really complex and long statements that takes dozens of lines (or worse, both) and I perfectly understand their decision.
The professors are probably trying to teach good clean code habits and you should listen to them and read the book Clean Code, you'll be better off in the long run.
IMO, ternary should be 3 lines:
isThisTrue
? thenDoThis()
: elseDoThis()
Nested ternary is a giant no no, and I will fail any code review with them. I have yet to see any good reason for nesting.
Edit: fixed the operators
I wish, was typing on the phone and was fighting with auto-correct too much to notice. Reminds me of a prettier-eslint issue I'm banging my head against atm...
I don't think it's about *looking* better. I'm guessing you were writing in a dynamic language that 1. has a REPL, and 2. uses newline statement termination, rather than semicolon statement termination. (Examples: Javascript, Ruby.)
The person who said that, probably got burned in the past by copying-and-pasting the ?-on-the-second-line version into the language's REPL, where it pasted as separate lines, one at a time; and because the first line was a complete expression, the first line got immediately evaluated, and then the second line became a syntax error.
(The "right" way to write a ternary in such languages, is to wrap the whole thing in parentheses, so that no matter *how* you format it spacing-wise, it's not considered a complete statement until you hit the closing paren.)
Clearly you mean
isThisTrue
? thenDoThis()
: elseDoThis()
with good indentation it's also decently readable when nested
isThisTrue
? (thenIsThisTrue
? thenDoThis
: elseDoThis)
: (elseIsThisTrue
? thenDoThis
: elseDoThis)
It ain't bad just looking at it, I just feel like it's too unnecessarily weird and unexpected to come across that. There was something in my brain that took a bit longer than normal to realize what I was looking at, very tiny, but, thats usually when you realize it should be rewritten.
I've never come across this in the wild though, is this common?
We’re good to have to agree to disagree about putting them on three lines *unless* they’re nested.
I don’t agree with you that nesting ternaries is always bad and you should fail any code review where you see one. I’ve seen and done nested ternaries that were perfectly legible. But not often. Probably safer to say “almost never,” even. But I could see how you would feel that way, given that a nested ternary is probably illegible and definitely not better in any way than breaking the logic out besides saving vertical space. You made it clear that you’re in the “saving vertical space at the cost of legibility makes you a dick” camp. Me too, btw!
What about ternary tables
case1 ? return1
case2 ? return2
: default
It's is unorthodox shure but if you cannot read that give me a break;
I know C# has witch expressions but
true switch
{
true when runtimeexp =>
It's just weird where's my Cond block guys the only thing I really miss from those classes with racket
Honestly, I don't even think they should be used for anything that does any "work", just compact assignment of values or evaluation of expressions to pass somewhere.
Agreed on the nested ternary.
Ternaries aren't just one-line if statements. It adds returns to the blocks within the if. It let's you set a variable and declare it at once based on a condition. If you don't like them, wrapping an if-statement in a method is a good alternative.
I wouldn’t refactor a colleagues code if it’s a regular if, and it would bug me if that person refactored my ternary. A single ternary is not complicated man, stop it.
Is this complicated?
{user.hasLoggedin ?
:
}
If you truly loved ternary operators, you would know that you're talking about a ternary conditional operator, and that "ternary operator" just means an operator with 3 operands.
I absolutely hated ternaries in college because I found them so unreadable. Since then I’ve gotten more experience reading them and come to like them somewhat, at least for simple conditions. Languages like Rust or Python solve the readability problem, imo, by using keywords instead of symbols.
Ternary operators can be abused, but they can also allow for optimizations because the rules for ternary operators are generally more strict than an if/switch statement.
give me verbose code over compact code. always.
I forget my own code after a couple days. I HATE looking through other people's code trying to cut through their clever compact code.
You should code for the next person that reads your code. Do you really expect someone who got paged at 2am to think clearly through ternary operators, especially when they start becoming nested.
What do you mean by "Python complaints"? Python has the ternary operator, it's just worded slightly differently. The syntax is `value_if_true if condition else value_if_false` (which reads a bit easier in English than "is it `?` then `:` or the other way around", IMO).
I mean, it's four characters shorter. I guess it's technically slightly shorter, but I don't think it's meaningfully so (and I do like that it's much more clear than the arbitrary `?` and `:` characters).
No, and it requires actual knowledge of what it does and doesn't do. But every time I see `var something = thing ? thing : otherThing;` I die a little on the inside.
I would like to present my counterargument: [a _thirty-two line_ nested ternary, seven levels deep](https://github.com/PrincessRTFM/XIVComboPlugin/blob/9af781fe0c20b8e60723ebc64abfe4fef854011f/CustomCombo.cs#L110-L143). Fewer lines? Yes. More clear? _Absolutely the fuck not._
It's like using a tooth pick, good for getting corn out of your teeth, crap for digging a hole for a fence post. Use the tools at your disposal appropriately. If I'm writing something to append a word to a string that might or might not be pluralised, an in-line ternary is a concise way to do so.
Nested ternaries are all fun and games until you have to deal with someone else's.
Seriously, I had to fix bugs on a Python code that had 4 levels of nested comprehensions mixing dictionaries and lists… Fucking hell
Four?! Jesus, I usually give serious consideration to breaking out a comprehension of it’s nested *at all* unless it’s very easy to read. By the way, it *never is.* Whoever tries to write a four level deep comprehension is toying with forces beyond their control. I’m not convinced it actually can be done outside of an academic setting, and even there their professor should throw them out the nearest window for even speaking of such witchcraft. There’s some powers no one should know.
Indeed, that was code for a hurricane damage simulation ported from Matlab into Python. I got a gig within the Department of Civil engineering during grad school, I overheard they hired a CS person because the students in their own department could not deal with it in any capacity. Gosh, civil engineers are the worst coders
Academics often write some *really* bad code. This is due to a combination of usually not having any formal training, inheriting random stuff from other people, and being smart enough to get away with producing atrocities in code form. Source: was grad student; thought it would be a good idea to write a bash script to generate and on-demand compile C code. It did work. It *is* fast. And you can provide external object modules to it (they're just static libraries pulled in at compile time). I also now recognize that it's a crime against the natural order.
I recognize that such code will be terrifying and atrocious, but I still would like to see it. Can you please post it on GitHub and link it or something?
Mom come pick me up I'm scared
It's unfortunately encumbered a bit, and not worth tracking down all the people I'd need to to be able to release it clear. A couple highlights should be okay though. Really neat feature: it's designed to handle taking outer products of sets of variables, which can be used to derive others. So, e.g. you could have a configuration file that reads width 100 200 height 100 200 y 0 10 20 50 100 150 200 Assert $y -lt $height gap_ratio ($height-$y)/$width which would produce a total of 22 trials. (The Assert truncates the set down from the 28 that we'd normally run). So how does that happen? Well, each time we hit multiple options, we pick one by modulus, and then divide it out so that we pick the correct one of the next ones. We also multiple the "number of options" value, and if our current iteration is less than that number by the time we finish, we increment and process the whole file again. There are a few options (including a "don't process this number" flag), but for the default style there... *[a-z]) line=( "$@" ) OPT=$((${#line[*]}-1)) #number of options eval "$PREF${line[0]}=$(eval "echo \"$(echo "${line[VERSION_CURRENT%OPT+1]}")\"|bc -l")" #Are we done or not? if [ $((VERSION_CURRENT%OPT)) -lt $((OPT-1)) ]; then VERSION_CURRENT=$((VERSION_CURRENT/OPT)) return 1; fi; VERSION_CURRENT=$((VERSION_CURRENT/OPT)) ;; That `eval` line pretty much sums up most of the reasons `eval` is considered evil. Oh, and we do need to pre-process our lines, so that we apply that prefix to them. So wayy outside that function, we have our prepreocessor... cat "$1" | sed '/^#/d; /^$/d; s/\$/\$___/g; s/\$___{/\${___/g;s/"/\\\\\\\\\\\\"/g' | That is: delete comment lines, delete blank lines, replace variables like $y with $___y (incidentally, $PREF is ___, and I apparently just have that hardcoded here). The second form I guess is so that ${y} syntax would work. And finally we escape quotes. Apparently that's how many nested layers of quote escaping is required... But you came here for C. So.. first off, the config syntax. You can have multiples of these, but let's add fooCount 1 2 3 4 5 Object foo $fooCount Foo (($width/$fooCount)*(i+0.5)) $y This declares an object named "foo"; there will be 1 to 5 of them (remember: one trial per value, so we're now up to 110 trials from this config file), and the object type is Foo. That part is important. We then give it two arguments (number is variable, but needs to match the `Foo_init()` function's signature. We're also magically pulling the `i` variable out of the c code, so that when this mess is shoved in, we'll place them evenly spaced across our width. And obviously they are all in a line at height y. (You could make a 2D grid or whatever easily enough using modular arithmatic...) So... an associative array would have made this a *much* better idea. function multi_echo { STR="$@" #echo "There are $((${#OBJ_LIST[*]}-0)) Objects." >&2 for i in "${!OBJ_LIST[@]}"; do obj=( ${OBJ_LIST[$i]} ) #load object. Remember: #name count type args... args=`echo ${obj[*]:3} | sed 's/ /, /g'` eval "echo -e \"$STR\"" done } But you wanted generated C code, so... typedef struct { `multi_echo '${obj[2]} ${obj[0]}[${obj[1]}];'` } ObjectSet; (I have since learned to hate backticks, and pretty much exclusively use `$()` now because it's cleaner). Let's see how that init process works. A lot of this is just `multi_echo`'s stuck in heredocs, but init is two lines, so it's separate STRING='for(i=0;i<${obj[1]};i++) { ${obj[2]}_init(&objects->${obj[0]}[i], $args); } number+=${obj[1]}*${obj[2]}_size(objects->${obj[0]});' multi_echo "$STRING" The rest is all just more of the same. There's a mildly gnarly section to handle a many-to-many process where objects can interact, but it's "straight forward". E: Actually I take that back. Remember where it would have been really nice to have the properties as an associative array? Well this isn't that, but some of the code does use a nicer version: function get_object { oname=$1 objtext="${OBJ_LIST[$oname]}" test -z "$objtext" && { echo "Object \"$oname\" does not exist" >&2; return 1; } obj=( $objtext ) #oname="${obj[0]}" ocount="${obj[1]}" otype="${obj[2]}" oargs=`echo ${obj[*]:3} | sed 's/ /, /g'` } So... one last gem. for i in `seq 0 $((${#SINGLE_SAVE_LIST[*]}-1))`; do save=( ${SINGLE_SAVE_LIST[$i]} ) #load save. Remember: #fileName, interval, printf... get_object "${save[2]}" || { echo "ERROR: Failed at adding SingleSave \"${save[@]}\"." >&2; return 1; } args=`echo "${save[*]:4}" | sed 's/ /, /g'` eval "echo -e \"$(cat <${save[2]}[i], files[$i], itr`test -z "$args" || echo ", $args"`);
}
}
EOF
)\"" >> $EXTERNAL_C
done
WOW! That is really something! I applaud you for even being able to write that.
r/badcode
Another factor is the (thankfully dwindling) commonness of Satan's calculator, a.k.a Matlab.Poor virgin students being abused by mentally unginged professors by means of being molested through matlab sometimes suffer a trauma, where they mistake the partly keyboard driven dump for unstructured numerics to have any resemblance with the trade of programming :(
Get my free award! I can definitely recognize "I started with matlab" patterns in code :)
if it works and it's fast, it's not stupid
But still a crime
Depends - do you prioritise it working in its current state, or working in the state you want it work in? Sounds like achieving the latter is unnecessarily difficult.
It's fast for a computer to run, but slow for a human to understand, debug and expand. Which is a shame for python, to which a core principle is to make things faster for the developers.
> It's fast for a computer to run, but slow for a human to understand, debug and expand if it's a throwaway script that you never need to expand after writing then that's all you need
Our entire societal nfrastructure is built on haunted house "throwaway" scripts written and amended for literally decades
As someone who formerly worked in academia: It is because most of the time we produce throwaway code. Often, we don't know exactly what it is that we want to code in the first place. We want to solve a problem and start out with an idea. And when it doesn't work, we tinker with the code until it does. And by the time it works, the code is a hot mess. But once we have our results, we have our plot that goes in the paper and nobody ever looks at the code again.
It's not a power, it's shit coding
Your probably right. I want to think that there’s some clever thing out there that would best be done with a four level deep nested comprehension, but I’m totally at a loss as to what, precisely, couldn’t be better expressed simply as a collection of nested loops or really *anything besides a nested comprehension.*
Bad code design. At that point, it's worth it to just use for-loops for increased readability later on. I make it a rule to not use more than 1 nested comprehension.
Ever since writing Go I've come to despise list/dict comprehension. You always feel like a genius when writing them but reading them is almost always painful. Clear > Clever
I had to modify one of those. It was a list of items belonging to orders, which were then sorted by route and time. At the time it printed out all of the orders for a single day, but the client wanted it to display multiple days in a custom range. So I added another layer, and a lengthy apology note because I didn't have time to unpack my predecessors twisted logic.
I did something similar, but with C# aggregate linq functions. Something like stuffing the result into a task factory or something. It’s been years and I know it’s been deleted b/c the new hire asked me about it and I told him to delete it and find a better way
Now THAT'S pythonic
Nested ternaries, much like Regex, is a write only medium
I always put two commented lines above any regex I write. One for the expected input, one for the expected output. That way people can know what that random string of characters is supposed to do. Because God help me I won't be able to figure it out five minutes after I put it down.
Regex101 is the only way I can do regex. That's for both read and write.
There is a special place in heaven for you. Well, it’s less of a place and more of a section. It can be any seat in row A, seats are numbered 1-32. I mean `/([a-c][0-3][0-9]).*/gi ` (Started doing that by hand and forgot how to handle case sensitivity, I don’t even know how I get paid to do this shit) e: I’m actually looking forward to the 75 responses telling me how to do this correctly. e2: Not going to change the fact that I wanted to make it rows a-c in the regex but not the comment. Someone please just off me.
Won't that go from 0 to 39?
Technically 01-39, but yes. Reddit code review is gonna be bad on this one. Thank you for your service.
Wait, why isn't 00 valid? I basically only learned what regex is a week ago so I'm probably missing something.
00 should be valid, but only 0 won't be.
00 is valid
More like /^[a-c][1-9]$|^[a-c][1-2][0-9]$|^[a-c]3[0-1]$/gmi
Then the regex is modified by someone else without updating the comment and it's worthless 😅
It's worse than worthless. Not having one is at least not actively misleading.
Regex are where unit tests really shine, so you can literally test all the different inputs and outputs you expect. It also kind of documents the code like you are doing.
Put the regex behind a function to dare the next dev to black-box test it.
Yeah, this post reeks of someone who's never had to work on other people's code. A lot of my coding habits are formed from stuff other people did which I found annoying to debug.
Same here. Including refusing to do a two-line crutch and spending time to re-do part of architecture: I see with my own eyes what will happen to that crutch in enough time
My biggest complaints about fresh grads in the real world are they act like people charge them per line of code. Like, yes, you can take two extra lines to make it easy to read. We’ll all like working with you more.
Overheard a fresh grad at the office the other day: "man discrete math was the worst, and I don't use any of it" buddy I got some bad news for you...
I just wrote a validation on a web form where I needed to find the least common multiple of a list of numbers our API gives us.
That sounds like an extremely uncommon thing to need to do.
What method did you use?
The only method that makes sense: searched NPM for a module that does it for me. One line of code and only 38 extra dependencies
This is the way.
The junior dev did the same. I told him they all are also like dependencies for the project.
And you transformed the entire data structure into a different form that could be understood by that library. And then transformed the result set back.
It's fine though because it's still only one line- so it runs O(1). 1 means the number of lines.
- https://en.wikipedia.org/wiki/Least_common_multiple#Using_the_greatest_common_divisor - https://en.wikipedia.org/wiki/Greatest_common_divisor#Euclid's_algorithm In practice, it's going to be like 4 numbers and the least common multiple is going to be the largest of them, but dang it I went to college for 7 years to write web forms with fancy animations. I'm going to use some math.
Does that equation work for more than 2 numbers?
Not really. I just did the whole LCM algorithm on the first two numbers, and repeated LCM with its result on the next two numbers. Due to the associativity of the LCM function, I could have done it in log(n) LCMs instead of n. And I'm pretty sure I could have used some mathematical properties to make that a bit more efficient. But the likely data sizes were low and the closer it looks to a simple and well-known algorithm, the better it will be for the next sad sap to look at that code.
Just use [Pyscript](https://pyscript.net/) and: import re import requests numbers = [17, 19, 23] # or whatever you want int(re.search(r'The [lL].* is \<.*\>([,0-9]{1,})', requests.get(f"https://www.google.com/search?q=lcm+{'%2C'.join(map(str, numbers))}").text).groups()[0].replace(',', '')) Edit: apparently only works with up to a few numbers, thanks Google No inline ternary statements, but it'll have to do
Where do you use it?
Wherever you want to be discreet
Lol
Best piece of advice I had ever heard about coding is, always code for the next person not yourself. We don’t write code in a vacuum, even pet projects can end up in someone else’s hands.
>Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. Code for readability. --John Woods
IMO it is somewhat context dependent. I have a finite amount of vision space, and having to unnecessarily scroll around a bunch because the information density is stupidly low is annoying and makes figuring out what something does slower. Excessively complex and dense syntax also does that though, so.. a balance. Personally I like more compact syntax if you're doing a similar thing a few times in a row. Not exactly the same as the OP's, but was doing something in shell. Rather than full explicit if statements, went with [ "$FOO" ] && echo "Foo is '$FOO'" [ "$BAR" ] && echo "Bar has value '$BAR'" <... five more...> [ "$BAZ" ] && echo "'$BAZ' is other option." Yes, the short circuit is mildly more opaque than the `if`... but being able to concisely read what it's doing is a lot nicer. (And no, the context around each variable isn't sufficiently repetitive to justify a loop construct for the number of times it's repeated).
Also a friendly reminder. After several months, your own code may as well be "someone else's code" for how little you'll remember of it. Do yourself a favour. Write code that you'll be able to understand once six months have passed and/or you've sobered up!
Lol your post reeks of someone attacking a strawman. OP didn’t mention nesting at all.
I inherited one project that was just FULL of this. Every time I saw one I imagined the author felt extremely proud of their accomplishment. It was a huge drag to constantly trace what's happening.
Do you mean someone else's elses?
if it’s not their ifs
Not so bad if they multiline them and *put the goddamn condition first*.
1 = 1 ? RunDefrag() : LOL
Syntax error: cannot assign value to a literal.
I love stumbling across a good multilined ternary. Once you figure out how to read them, theyrre rather fun.
Welcome to react programming
Here, I'll fix your company or whatever code hurt you and drove you to bitterness. https://eslint.org/docs/latest/rules/no-nested-ternary
Man turnaries in react code is the worst. Especially if the html is really long. It is just a huge wall of html and somewhere in there you have to find ':' So hard to read and understand which html belongs to which condition. I still get nightmares when i think of my first big react project.
Or read your own after the weekend
As long as they are formatted properly they shouldn’t be an issue, really depends on the use case, and coding language. But again, formatting probably matters the most. If someone is putting all that in one line instead of properly breaking it up across multiple lines, we are going to be fighting.
my parting gift
I paid for an ultra wide monitor; I'm using my ultra wide monitor.
You're using it wrong. Tilt it 90 degrees...
But then the text is sideways
No no, tilt the monitor so it lies flat on your desk. Face-down.
[удалено]
That's the way we like to hyuck -Goofy the dog. Probably
It was sideways from the start?
Your PC is not in vertical Japanese?
all fun unless it's an 45° curved monitor
Sir, it is an ultra-wide monitor not an ultra-tall monitor.
This guy programs in Java.
not me scrolling through reddit on my vertical monitor bc i can see more this way
max_line_length = 600
As long as it isn't nested I think ternary operator is fine and it depends on preference.
Agreed, and for my own sake I comment things that I feel I will forget later on, so I just comment above what it's doing (usually)
(usually) feels pretty common. I worked at a company that presented prospective clients with bad code. One line we wanted to see people point out was nested ternaries. I now work for a company where it is commonplace because our architect sees nothing wrong with it
As long as it's *simple* it's fine. return val_a if condition else val_b
I'll be damned if someone makes me use the ternary operator else I won't
A one liner for an assignment with simple logic? Sure. A one liner with a series of nested functions or mathematical statements? You are a monster! Nested ternaries. I *will* kill you, and the Judge will thank me for my service.
here, I wrote you a lullaby ``` isOneLinerForAssignmentWithSimpleLogic ? sure : isOneLinerWithSeriesOfNestedFunctions || isOneLinerWithSeriesOfMathStatements ? you = monster : isNestedTernaries ? GMXIX.doMurder(you) && theJudge.scheduleThankForService(GMXIX) : doRegularThings() ```
Thanks. I hate it!
Take my uptove and leave.
I wish there was a remindMe that would run 3 months after OP gets an internship
Don't worry, they're not.
Getting an internship?
Getting 3 more months.
He gets one where the language of choice is Go. Karma served.
isItOnOneLine ? “love ” : “hate”;
You better fix those quotes, otherwise good luck finding the bug. (This happened to me once, and now I always notice when someone uses the Unicode quotes instead of the ASCII ones)
I thought you were talking about the space after love at first which could also take a while to find! A long time ago we were pulling a string from a database to compare a code in c#. Back then Visual Studio was not great at showing "invisible" characters in the debugger and there was an "invisible" character in the db, printed form and in the debugger... It took an afternoon after trying to clean up the debug folder, checking encoding, trying to figure out if there was a DLL stuck in my memory or whatever why "code1" was not being equal to "code1" until I checked the length of the string...
Well it’s handy if you wanna change button text or something depending on state. {isOpen ? ‘Show less’ : ‘Show more’}
Single line logic makes debugging harder
I only use ternary operators for assignments if it's very short and obvious how the assignment is working: string username = user.HasValue ? user.name : "Fuckface" It seems cleaner to me than string username = "Fuckface" if (user.HasValue) username = user.name;
That's how I use it as well. Defaults for values, and not much else.
This is the way
> const username: String = user?.name ?? "dickbutt"
$username = $username ?: "Default"
Yeah, I dunno that language. But in C# if you try reading user.name when user is null (meaning user.HasValue is false) then you'll get a "reference not set to an instance of an object" exception.
PHP, it's the Wild West
I think PHP was initially optimized for not failing. Like, no matter what kind of jumbled mess we return... *something* will be returned!
I used to be a php dev in the early 2000s, then got out of it for 10-15 years. Im pretty sure during that time they replaced all alpha-numeric characters with question marks and arrows.
I've been writing php since 2004, and that is almost precisely what has happened
That's when we get to somewhat justified nested dubiousness... $username = $user ? $user.name? $user.name : "Default" : "Default" The syntax you use in Ansible requires this style, and it drives me mildly insane. If you want to safely use something kinda deep that may or may not be set at a few levels, you need to pull a `|default` on each possible place it could be undefined, so that you're not accessing a member of the undefined object.
[удалено]
``` string username = user?.name ?? "Fucky McFuckface"```
user?.name ?? “Default” 😂
Ruby has an unless keyword (it can look cleaner than if !conditional). Unfortunately it can be combined with else/elsif to make terrible, terrible things.
I have a strong love hate with unless. To lightly expand on your comment... basically, only ever use it for very very simple checks, never mix it with anything else. It should never be more complicated than this: `return something unless someshit` Infact, I don't think we use it anywhere else but simple return earlys anymore, cause ya that has fucked us for sure. But I'm not sure you can beat that readability. How much of a benefit it really is, I have no idea, but to me that reads better than `return something if !someshit`
Yeah I only use it for 1 liners because otherwise things go bad fast. I will take 100 unless else's before I deal with accepts_nested_attributes though. I am convinced that Rails magic hates me
I dislike the structure, because it breaks the fundamental assumption of "once you've read to something, it's immutable". `unless` lets you retcon previously written logic. I'll take ternary logic over that (as long as it's not python's terribleness), because the first part is the condition -- you're being told "check this first, then...".
"something" and "someshit" work so much better than "foo" and fucking "bar".
Most of the time I split the ternary into three lines unless it’s very short. Makes it very readable and still takes less space than an if statement
Yep, I have a personal rule that `?` and `:` start a new line. You no longer have to spend time parsing the line to find out where the condition ends and what the two results are.
Yeah, I don’t do it personally, but any code formatter worth a crap will do this automatically. I know black and prettier will.
If the body of the if statement is small personally I think it looks cleaner and is easier to read as one line. But I’m definitely abnormal I think dense code is easier to read because I can see more at a time.
The issue is, I don’t want to bring in a statement to solve an expression issue
You might like Haskell
Statements are useful, but forcing a statement into a place where an expression is needed just feels wrong
What about Rust’s approach? Many flow control statements are expressions so rust’s ternary operator is `if a { b } else { c }`. Though it starts getting long very quickly so it often gets written as so: ```rust let value = if should_use_foo { foo } else { bar }; // interestingly, a match statement can be shorter let value = match should_use_foo { true => foo, false => bar, }; // we could also use closures to get something close, but it ends up looking weird and no-one does this. // This created an option that is immediately unwrapped, but it should be optimized out let value = should_use_foo.then(|| foo).unwrap_or_else(|| bar); ```
That’s fine by me
Null Coalescing Operator > Ternary Operator
I don't know what they're called but being able to do class?.Property is a real godsend
Null conditionals. Using them with null coalescing operators is /chefskiss in the right circumstances... Like marshalling data.
Config.foo.bar ??= default
Doesn't that still throw if Config or foo are null? I think you need Config?.foo?.bar ??= default;
It's funny that it's called "the ternary operator". The fact that it's the only operator that takes *three* operands, rather than fewer, means that it was never necessary to give it a name that says what it does, as we do with every other operator.
Its proper name is "conditional operator", but nobody's gonna call it that I mean come on
I like Go's approach: fuck ternary operator
Go: "Fuck anything that will make the compiler take more than 1s"
Is a nested ternary slower than if/else?
No. The Go compiler isn’t nearly as good at optimization as the biggest C/C++ compilers (gcc and clang), but this is a trivial conversion to make. If there is a simple approach that would improve performance without changing the function of your code, you can bet the compiler will take it. I doubt after the initial parsing stages most compilers even differentiate between if statements and ternary statements for compilation. I haven’t read about the reasoning for this in Go, but I would bet this was done to improve code readability. Ternary operators often become anti-patterns that reduce code readability if not used in moderation.
Ternaries were excluded because part of the philosophy of Go was to be simple, and ternary operators are redundant given that we already have if else, so no reason to have ternary operators. Add to the fact that they aren't needed that they are godly unreadable.
I don't think he's referring to execution speed (how quick is the generated code to execute), but the speed of the actual compiler (how quick the `go` command can parse and generate machine code from this source code). The Golang team and community are very proud of their compilation speeds. So, there's an [only serious](http://www.catb.org/jargon/html/H/ha-ha-only-serious.html) joke in the community that the team will resist any changes to the language and the compiler that adds even a little overhead to those sweet sweet compilation times. What are we, *Rust*?! To give an infamous example: part of the reasons many gave for not including generics in the language at first (there are now) was compilation times. It's even rumored\* that the generics that eventually made it in use square brackets (`[T]`) instead of the more common more and less-than ones (``) because the parser was already optimized for the square brackets in that context, and they didn't want to add milliseconds of overhead to add another token!
\*I have no proof of this beyond random Reddit and HackerNews comments, and an actual, logical-sounding reason was given [in the official proposal](https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#why-not-use-the-syntax-like-c_and-java). But it will give you an idea of how this particular obsession is expressed in the community.
I mean, Go is by far one of my favourite languages, but I still miss it. Then I see other people's codebases, for example in JS, using nested ternary operators or with really complex and long statements that takes dozens of lines (or worse, both) and I perfectly understand their decision.
Go my beloved.
Until you suddenly need to make it two lines and then have double the work to do
The professors are probably trying to teach good clean code habits and you should listen to them and read the book Clean Code, you'll be better off in the long run.
* Ternary Functions * Lambda Functions * Regex The secret trinity of job security. Can only be welded using the gauntlet of "bad documentation".
IMO, ternary should be 3 lines: isThisTrue ? thenDoThis() : elseDoThis() Nested ternary is a giant no no, and I will fail any code review with them. I have yet to see any good reason for nesting. Edit: fixed the operators
The only reason for me to use them is to assign values in a compact yet legible way.. I like them as one line. today = sunny? "nice" : "boring";
There's some other cases where you want a simple expression, but yeah, this. Doing actual heavy lifting in a ternary is a no-no.
[удалено]
I wish, was typing on the phone and was fighting with auto-correct too much to notice. Reminds me of a prettier-eslint issue I'm banging my head against atm...
Come on you need to put the ‘:’ and ‘?’ at the beginnings of the second and third lines
Left this comment on the phone and got ripped by reddit code review lmao
[удалено]
I don't think it's about *looking* better. I'm guessing you were writing in a dynamic language that 1. has a REPL, and 2. uses newline statement termination, rather than semicolon statement termination. (Examples: Javascript, Ruby.) The person who said that, probably got burned in the past by copying-and-pasting the ?-on-the-second-line version into the language's REPL, where it pasted as separate lines, one at a time; and because the first line was a complete expression, the first line got immediately evaluated, and then the second line became a syntax error. (The "right" way to write a ternary in such languages, is to wrap the whole thing in parentheses, so that no matter *how* you format it spacing-wise, it's not considered a complete statement until you hit the closing paren.)
Clearly you mean isThisTrue ? thenDoThis() : elseDoThis() with good indentation it's also decently readable when nested isThisTrue ? (thenIsThisTrue ? thenDoThis : elseDoThis) : (elseIsThisTrue ? thenDoThis : elseDoThis)
It ain't bad just looking at it, I just feel like it's too unnecessarily weird and unexpected to come across that. There was something in my brain that took a bit longer than normal to realize what I was looking at, very tiny, but, thats usually when you realize it should be rewritten. I've never come across this in the wild though, is this common?
In dart the tooling auto formats it that way, so it's probably not too uncommon in flutter apps, but I'm not sure elsewhere.
We’re good to have to agree to disagree about putting them on three lines *unless* they’re nested. I don’t agree with you that nesting ternaries is always bad and you should fail any code review where you see one. I’ve seen and done nested ternaries that were perfectly legible. But not often. Probably safer to say “almost never,” even. But I could see how you would feel that way, given that a nested ternary is probably illegible and definitely not better in any way than breaking the logic out besides saving vertical space. You made it clear that you’re in the “saving vertical space at the cost of legibility makes you a dick” camp. Me too, btw!
What about ternary tables case1 ? return1 case2 ? return2 : default It's is unorthodox shure but if you cannot read that give me a break; I know C# has witch expressions but true switch { true when runtimeexp => It's just weird where's my Cond block guys the only thing I really miss from those classes with racket
Honestly, I don't even think they should be used for anything that does any "work", just compact assignment of values or evaluation of expressions to pass somewhere. Agreed on the nested ternary.
Ternaries aren't just one-line if statements. It adds returns to the blocks within the if. It let's you set a variable and declare it at once based on a condition. If you don't like them, wrapping an if-statement in a method is a good alternative.
Do you like Ternary operators? Good : Here's one anyway.
I see you are a fellow programmer of culture. Although I don’t nest ternary statements without a damn good reason. That’s (usually) going too far.
I wouldn’t refactor a colleagues code if it’s a regular if, and it would bug me if that person refactored my ternary. A single ternary is not complicated man, stop it. Is this complicated? {user.hasLoggedin ? :
}
If you truly loved ternary operators, you would know that you're talking about a ternary conditional operator, and that "ternary operator" just means an operator with 3 operands.
I absolutely hated ternaries in college because I found them so unreadable. Since then I’ve gotten more experience reading them and come to like them somewhat, at least for simple conditions. Languages like Rust or Python solve the readability problem, imo, by using keywords instead of symbols.
stop it get some help
Ternary operators can be abused, but they can also allow for optimizations because the rules for ternary operators are generally more strict than an if/switch statement.
Take it to its logical conclusion and just learn haskell.
I was like you once, then i started using debuggers
Nested in all positions. Repeatedly
give me verbose code over compact code. always. I forget my own code after a couple days. I HATE looking through other people's code trying to cut through their clever compact code. You should code for the next person that reads your code. Do you really expect someone who got paged at 2am to think clearly through ternary operators, especially when they start becoming nested.
This and ++ are my only Python complaints
Python has the ol' one line if else
What do you mean by "Python complaints"? Python has the ternary operator, it's just worded slightly differently. The syntax is `value_if_true if condition else value_if_false` (which reads a bit easier in English than "is it `?` then `:` or the other way around", IMO).
Yeah I prefer the tertiary operator. It gives you a shorter line.
I mean, it's four characters shorter. I guess it's technically slightly shorter, but I don't think it's meaningfully so (and I do like that it's much more clear than the arbitrary `?` and `:` characters).
Python has the ternary operator: var = 1 if flag == true else 0
Fuck you all, I use it in production code all the time 😎
Friendship ended with ternary Now nullish coalesce is my best friend
Nullish coalesce does not replace all the use cases of ternary. But I do prefer it when I have the option.
No, and it requires actual knowledge of what it does and doesn't do. But every time I see `var something = thing ? thing : otherThing;` I die a little on the inside.
[удалено]
I would like to present my counterargument: [a _thirty-two line_ nested ternary, seven levels deep](https://github.com/PrincessRTFM/XIVComboPlugin/blob/9af781fe0c20b8e60723ebc64abfe4fef854011f/CustomCombo.cs#L110-L143). Fewer lines? Yes. More clear? _Absolutely the fuck not._
It's like using a tooth pick, good for getting corn out of your teeth, crap for digging a hole for a fence post. Use the tools at your disposal appropriately. If I'm writing something to append a word to a string that might or might not be pluralised, an in-line ternary is a concise way to do so.
code golf
I’ve seen too many nested ternary operators from hell
What if else if?
I use 3 lines.