Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Volte
Oct 4, 2004

woosh woosh

Absurd Alhazred posted:

So in C++ if I define:

then a function that accepts JustAString&s would refuse to compile with AStringAndAnotherThing&, even though theoretically I could have also written:

and then it would be fine. You're saying TypeScript doesn't see a difference between these two?
It's not that it doesn't see a difference, just that they are related. In TypeScript, the type is the structure. The name you give it is just an alias for that particular structure. Any two aliases of the same structure are the same type. And due to structural subtyping, the type structure aliased by AStringAndAnotherThing is a subtype of type structure aliased by JustAString, so you can use value that conforms to AStringAndAnotherType whenever a value that conforms to JustAString is expected (but not vice versa).

Adbot
ADBOT LOVES YOU

Volte
Oct 4, 2004

woosh woosh

LOOK I AM A TURTLE posted:

It does enforce nomimal typing for class objects, but not for "plain objects".
This isn't the case. Typescript doesn't distinguish between classes and other types, and your first example would compile fine if you passed the correct number of arguments to the B constructor. The explicit inheritance mechanic is part of JavaScript's class system and is necessary to maintain that inheritance relationship at runtime, but the same structural subtyping rules apply regardless of inheritance.

edit: :rip:

Volte
Oct 4, 2004

woosh woosh

Absurd Alhazred posted:

If TypeScript doesn't change its behavior if I change something then I'm going to call it "it doesn't see it". :shrug:

Eugh, I just hope I never get pushed into webdev.
It's the exact same relationship as in C++ if the inheritance was specified. It's not that it can't see the difference between the base class and the subclass, it's just that they are both compatible with that particular parameter. If you tried to implicitly cast the other way, both languages would fail to do it for the same reason.

Volte
Oct 4, 2004

woosh woosh

Absurd Alhazred posted:

That's exactly it, though: I don't want my compiler/interpreter helpfully finding these underlying structures for me, I want it to raise the alarm that I passed something in that wasn't explicitly allowed.
You are explicitly allowing it by defining the structure that way. It's not a helpful compiler shortcut, it's a fundamentally different kind of type system. The name of a type simply does not matter beyond documentation. You don't even need to use the name of the type to reference it, you can directly write out the structure. If you actually want to enforce name identity, you'd have to build that into the structure of the type.

There are some ways to enforce nominal typing (for example) but I wouldn't say it would be desirable all the time.

Volte
Oct 4, 2004

woosh woosh

Absurd Alhazred posted:

You keep using the word "explicit". I don't think it means what you think it means.
If you define a function that says "I will accept any object that has a string called 'name'" and then you define an object that has a string called 'name', that's being pretty explicit about the conformance of one thing to the other.

Volte
Oct 4, 2004

woosh woosh

Absurd Alhazred posted:

But that's not what I'm doing. I'm saying "I accept SpecificallyThisObject", that happens to have a string in it. I don't want it to accept "ThatEntirelyDifferentObjectThatHappensToStartWithAString" without me explicitly enabling that behavior somehow because it detects that there's this structural similarity and just "helpfully" does that for me.
If you don't want it to accept that then you should not define your intended interface in a way that unambiguously has a subtype relation with it. You claim you're saying "I accept SpecificallyThisObject" but in TypeScript, you are not saying that because it can't be said. You can encode a nominal identity inside the structure (like { name: string, kind: "SpecificallyThisObject" }) if you want, but at the language level, the name of the type is not important to type checking, full stop.

Volte
Oct 4, 2004

woosh woosh
It's incorrect because you can't pass JustAString in a place where AStringAndAnotherThing is expected. If it didn't see a difference between them, that would obviously not be the case. There's a big difference between "A and B are both acceptable" and "A and B are indistinguishable".

edit: I think I misunderstood by what you meant by "these two". I thought you meant the types, not the two examples. I guess we're arguing for nothing.

Volte
Oct 4, 2004

woosh woosh

Absurd Alhazred posted:

With all the stupid garbage they poured into C++20, it would have been nice if they had made * and & first class type modifiers instead of variable-attached type modifier.
That would be backwards incompatible.

Volte
Oct 4, 2004

woosh woosh
I frankly would prefer that the C++ ecosystem didn't get hard rebooted. I've had enough of that with .NET thank you.

Volte
Oct 4, 2004

woosh woosh

Xarn posted:

The issue with all the changes around <=> and comparison reordering and stuff is that they can silently cause new and cool issues with previously valid code.

It would be great if it was in for C++98/03, so that people would write valid code for it, but since we get it in C++20, it will be lot of "fun" to update everything.
What issues is <=> going to cause (other than a potential lexer quirk that will in practice almost never come up)?

Volte
Oct 4, 2004

woosh woosh

Xarn posted:

The output is different with C++17 and C++20.
Interesting example. I assume that's because the implicit conversion to const char * is tricking std::pair into thinking the spaceship operator is defined and causing it to defer to the incorrect comparison?

Strictly speaking the comparison operators on that type are broken even in C++17 though, since s1 < s2 is checking a fundamentally different thing than s2 > s1.

Volte
Oct 4, 2004

woosh woosh

Phobeste posted:

Oh didn’t know, my bad. Wonder why I thought it was
Maybe you're thinking of OCaml?

Volte
Oct 4, 2004

woosh woosh
My CS degree was mostly “here’s the language we’re using in this course, here are some links to learn it if you don’t already know it”. We did do one C++ class but it was mostly about software design concepts and not the language itself.

Volte
Oct 4, 2004

woosh woosh

ultrafilter posted:

You can't evaluate introductory courses just based on how well the students like them. That's a recipe for disaster.
Introductory courses that the students hate are a recipe for dropping out instantly

edit: No matter what the introduction is, the students are going to be learning bad habits and misconceptions that they need to break later, so you might as well start with the thing that gives them the least friction. I love strong static typing and very much dislike dynamic typing, but only because I went through a phase of loving dynamic typing, learning some hard lessons, and realizing how hard it is to architect a solid system that I'm confident in with dynamic types. At best if you teach students how great static types are to begin with, they're going to essentially be cargo culting it (or rebelling against it) for superficial reasons that they can't possibly understand intuitively. Experience is the only true teacher of these things - the best introduction is the one that makes students want to know more and keeps them interested.

Volte fucked around with this message at 15:52 on Oct 24, 2022

Volte
Oct 4, 2004

woosh woosh
I've seen that template technique before in C, but it just used GNU M4 or whatever and didn't get cute with weird characters. I guess using valid identifier characters keeps the syntax highlighter happy but any kind of IDE or analysis tool is going to break anyway.

Volte
Oct 4, 2004

woosh woosh
There's nothing wrong with this :colbert: And it's still a percentage. 0.1 and 10% are the same thing: 10/100.

Volte
Oct 4, 2004

woosh woosh

leper khan posted:

percentage = .1 says very explicitly .1/100
It doesn't. The fraction is the percentage and the % sign is a shorthand for "x/100". Percentage refers to a fraction of 100, it doesn't specifically mean just the numerator.

Volte
Oct 4, 2004

woosh woosh
It's pretty simple: there's no place that you should ever see "percentage" and assume it should be an unadorned number between 0 and 100. There's nothing in life, programming, or mathematics that uses it that way. Not even everyday use of percentages in common language express percentages without the percent sign.

Normally this wouldn't even come up, since you rarely need to specify "percentage" instead of something more general but since this is specifically designed to visually represent percentages, it makes sense to me that it should follow the definition of what a percentage actually is, and not what some people might mistakenly believe a percentage is.

Volte
Oct 4, 2004

woosh woosh

leper khan posted:

Per Centum. Fraction of 100. It's literally the words meaning. 10 percent is 10/100. .1 percent is .1/100

Per Mille. Fraction of 1000. 10 is 10/1000. .1 is .1/1000

It's very explicit.
But you're mixing up two different words, percent and percentage. A percentage is a fraction of 100. Percent is just a shorthand for "out of 100" or "divided by 100". "10 percent" is the percentage 10/100 = 0.1. "0.1 percent" is the percentage 0.1/100 = 0.001. I would understand this complaint if the name of the function was "percent" instead of "percentage", but in that case I'd say it's just wrong and there's no real good interpretation of that. Percentage is pretty unambiguous though.

pokeyman posted:

It's pretty simple: my interpretation is obviously correct and you're all idiots.
I meant keeping track of when to interpret it as a fraction instead of a whole number is simple: always (another post snuck in there and maybe made it less clear who I was responding to)

Volte
Oct 4, 2004

woosh woosh

leper khan posted:

percentage
a part of a whole expressed in hundredths
https://www.merriam-webster.com/dictionary/percentage

Yes it is unambiguous. A percentage of .1 would be .1/100
"A part of a whole" is literally the definition of a fraction and 0.10 is already expressed in hundredths. It's ten hundredths. That's what the decimal notation means. You can argue the nuances of naming functions and whether this term confusing to the average reader (I'm starting to come around that it is confusing, but certainly not incorrect) but as far as the definition of percentage, you're mistaken.

If the language had an actual % postfix operator that let you specify "50%" directly, what would you expect "printPercentage(50%)" to do?

Hammerite posted:

like, even if I agreed that "proportion" and "percentage" were terms that have absolutely 100% the same meaning and connotations (I don't agree, by the way) I still wouldn't name a variable that if it was meant to be an ordinary proportion; because I would know that the majority of people reading the code would not understand it to mean what I was trying to express, and if writing code is an act of communication with the computer and with other programmers, then that's a failure to communicate well
I'm not sure exactly what distinction you're drawing between an ordinary proportion and a percentage, but it's called a percentage because the function is specifically is designed to visualize percentages.

cheetah7071 posted:

this is absolutely wrong. Completely wrong. I see numeric values between 0 and 100, intended to be interpreted as percentages, constantly in my work.
File a bug report

Volte fucked around with this message at 22:04 on Jan 17, 2023

Volte
Oct 4, 2004

woosh woosh
I think at best it shows that there needs to be some clarification on the range, which really there should be in any case, but I still don't think there's a better word for that function than "percentage" given what it does (maybe ratio but I think that tends to connotes a proportion of one thing to another). A lot of colloquial usage has implied information omitted in ways that you would (or should) never assume in a more rigorous setting like programming. "What's the temperature?" "31". In common parlance, this is probably a well understood sentence given all available context. In programming, it would be obviously underspecified - if it wasn't obvious otherwise, you'd have to go to the documentation to see what units are expected. If you see "percentage", maybe you do the same thing just to make sure because sometimes the meaning of words can be tricky, but I still say that if the documentation then tells you the number should be between 0 and 100, then it's a misnomer. In other words, if you assume "percentage" means anything other than "scalar multiplier of a whole", then you're just assuming that the library writer was wrong. Bury me on this hill :colbert:

Volte
Oct 4, 2004

woosh woosh
The parameter should be called "n" so that you have to look up what the range is.

Volte
Oct 4, 2004

woosh woosh

Dijkstracula posted:

this is all correct of course - though, the original method was written in Java and I've had cases where I wanted something along the lines of value numbering to be applied, but only the server compiler actually did it when I inspected the assembly. (maybe getPercentageRounds() is called often enough that it trips the recompilation threshold though :v: )
It clearly specifies that the original method was written in C# though

Volte
Oct 4, 2004

woosh woosh

Athas posted:

Why is it called libcef.dll and not something more descriptive? I am a big fan of terse names, but I don't get the point of terseness for things you will not regularly type, but which you might need to spot in lists.
It's the Chromium Embedded Framework library (CEF) so it seems reasonable to me. I don't think anyone names their libraries according to whether you're going to need to spot it in a list.

Volte
Oct 4, 2004

woosh woosh

Athas posted:

Maybe they should. There is nothing gained by calling it libcef.dll instead of libChromiumEmbedded.dll or whatever, and the latter saves you from having to look up what cef means. It's not like you type this name often while programming. I think I have found the obscure complaint that I will build my grave on.
Okay, but

Volte
Oct 4, 2004

woosh woosh
My favourite Windows start menu search behaviour (which thankfully seems to be fixed in Win11) was typing "VLC" and the first highlighted result was "VLC media player - reset preferences and cache files" instead of the main application.

Volte
Oct 4, 2004

woosh woosh
I like the drive letter system personally, and Windows supports mount points instead of drive letters for additional volumes if you really want that.

Volte
Oct 4, 2004

woosh woosh

Remulak posted:

I love the Windows Store python setup, I can send our field support python scripts without spending a ton of time helping them gently caress around with paths and installers.
They should just bundle Python directly and I have no idea why they don't.

The Bash vs Powershell fight is funny to me because they're both incomprehensible garbage as far as I'm concerned. I've had to write bash scripts on occasion for like 20+ years and I still have to consult a reference to figure out how to do basic control flow constructs.

Volte
Oct 4, 2004

woosh woosh

Jigsaw posted:

If I can’t walk somewhere, I use a rocket ship.
What is the middle ground between walking and a rocket ship in this metaphor?

Volte
Oct 4, 2004

woosh woosh
It seems like it's as simple as they did Prefs.Set(key, value) except without realizing that 'key' is different with every run. Unity is the thing that spams it into the registry. The idea that this is some absolute nuclear fuckup by the KSP devs and they should never be trusted to write code again is hilarious.

It reminds me of when I used to work in a computer shop around 2008 doing tech support and someone had brought in a computer that didn't work properly, and the issue turned out to be that some Kodak photo printer software (if I remember correctly) was creating tiny files in a temp directory at a rate of several per second any time the computer was on. It had created so many junk files, we're talking like hundreds of millions of files, that Windows just didn't really work anymore. Now there's a flaw I could see getting upset over.

Volte
Oct 4, 2004

woosh woosh

Bruegels Fuckbooks posted:

I can forgive a programmer missing this but no one in their QA noticed this? It's a combination of "run your game long enough and game doesn't work anymore" and "dumps thousands of mb of keys in the registry" - that kind of bug is a QA wet dream.
This seems like a bug that only happened each time the game was loaded and took months of frequent play on the same user profile to occur, so I would characterize it more as a QA nightmare. It didn't "dump" hundreds of MB of keys into the registry (and the actual amount of data in the registry would have been several times less than that -- the 300+ MB file is a .reg file with all the data dumped into a comma-separated hexadecimal-encoded listing), it trickled them in slowly until suddenly the game stopped working.

If I had to point the finger at any one clear point of failure, it's Unity, because what the hell, why does it store user preferences in the registry??

Volte
Oct 4, 2004

woosh woosh

ExcessBLarg! posted:

Unity is why a 850 MB pixel art game takes up 7.1 GB on Nintendo Switch. Absolute weird bullshit engine.
Any info on this? I can't find any technical information about it or reason that it would be Unity causing that and it doesn't seem to be an issue for other Unity games.

Volte
Oct 4, 2004

woosh woosh

Macichne Leainig posted:

I mean, the evidence is that the original game is 850mb on disk. It's gotta be some asset packing fuckery to blow it up to almost 10x its size or some other weird poo poo.
I was very curious about this so I :ninja: obtained :ninja: a ROM of the Switch version and unpacked it. The total size on disk is 3.51GB instead of the 854MB of the PC version. The Switch version has way more bare data files and they are much larger. The PC version has a 177MB file called "unity3d.data" which is absent on the Switch version. I found reference to a similar issue in this thread which leads me to believe that is a compressed asset bundle and its use depends on the platform settings when building. When I use "Asset Bundle Extractor" to decompress it, it becomes 6.1GB. I believe many of the files' contents are Unity's YAML descriptors of various nearly-identical game objects which explains why it is so highly compressible. Not sure why the Switch version is only 3.5GB instead of the 7+ reported elsewhere, unless that's just a 2x size buffer to account for patches or whatever.

So I'm not sure I'd lay this directly at the feet of Unity. I would guess either whoever built the game didn't set the build up with compression enabled properly, or else it was determined that the Switch hardware didn't play nicely with on-the-fly decompression. Anyone know how big the PS4 version is?

Volte fucked around with this message at 21:47 on Sep 26, 2023

Volte
Oct 4, 2004

woosh woosh

Macichne Leainig posted:

I didn’t say it was all Unity’s fault but go on I guess
Someone else did


edit: Looking back in the Steam depot history it seems that it was originally uncompressed on PC as well, and they switched to a compressed build shortly after release. So it could just be that the consoles never got that change. See: https://steamdb.info/depot/774362/history/?changeid=M:936010028863753902

Volte fucked around with this message at 22:00 on Sep 26, 2023

Volte
Oct 4, 2004

woosh woosh

leper khan posted:

You shouldn't have a need for a null value type IMO. Though sure that's a real use case of something they do that's different.

How is use after no longer has value different than use after free?
Forget the word "null", it's distorting your viewpoint. Option is effectively a list that can have either zero or one element in it, and as a result you can basically use all the nice patterns that you can use with lists (and a few others that come from the zero-or-one property too). Null specifically means an invalid pointer, and it is sometimes (mis)used to represent the "empty list" case, but None and null aren't the same thing.

Volte
Oct 4, 2004

woosh woosh

leper khan posted:

Null is the absence of value. The concept isn't unique to pointers.
I was using your own definition of null from this post, which you explicitly called out as being a pointer:

leper khan posted:

Horror from the thread and all, but I never understood the appeal of option types. Doesn't give any more information than a pointer.

You don't solve the problem of having null data. And you potentially confer that problem on to _value_ types, which implies you don't understand how data enters your system.

Oh you have to check HasValue everywhere instead of != NULL. Wow great good job.
Option types don't give any more information than a pointer because (in the environments we're discussing here) all pointers are implicitly optional. That's the entire problem. The problem you called out of having to check HasValue everywhere is exactly why option types are good and useful - because when Option<T> exists to represent "either T or nothing", then you can use just T by itself to represent "definitely T". When you have a "definitely T" there's no need to check HasValue, and it makes it clear by the types when the value might be missing and even where the lack of a value came from. But in your average language with null pointers, there's no such thing as a "definitely pointer", so you always have to check. You could eliminate the concept of a null pointer all together and replace it with Option<Ptr>, which is incidentally exactly what (safe) Rust does.

Volte
Oct 4, 2004

woosh woosh

ExcessBLarg! posted:

I'm struggling to think of a good example of having 100+ "else if" blocks even for generated code. Surely it could be converted to some kind of dispatch mechanism, or at least convert the conditional tests into a tree form.
The idea of having to do one of a large but static number things based on a discriminator value isn't very strange. One example off the top of my head that could come up even in non-generated code would be something like implementing an interpreter/recompiler for an instruction set

if (opcode == FOO) { ... } else if (opcode == BAR) { ... } else if ...

Yes, it can be trivially converted to other forms that don't run up against the limit, but there's no inherent reason you'd start there when something as simple as this is the lowest hanging fruit and adding in a dispatch mechanism isn't necessarily going to be good for performance.

Volte
Oct 4, 2004

woosh woosh

ExcessBLarg! posted:

This could trivially be written as switch/case even within a code generator.
Nobody has argued that it's the only way to write it, just that it is a place where it could conceivably come up in a non-horror situation. And a switch only works in the event that all of the conditions are simple single-value comparisons.

Volte
Oct 4, 2004

woosh woosh
"VERY few engineers out there could write it from scratch" [citation needed]

It's not even that complicated of a type. C++ programmers are writing similar things with template behemoths and SFINAE all the time (god help them and us all). They'd probably kill to have it as easy as just a bunch of nested type-level conditionals with clearly defined and understandable conditions.

Adbot
ADBOT LOVES YOU

Volte
Oct 4, 2004

woosh woosh
I don't think there's anything that gross about it that's not also gross about any switch statement that uses fallthrough logic. The fact that it slices up the for-loop construct is kind of viscerally offputting but starting partway into the for loop isn't really conceptually any different than a do-while loop. It's what I would mildly classify as spaghetti code and not something I would ever do in general, but it's pretty clear what it does and how it works.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply