Hacker Newsnew | past | comments | ask | show | jobs | submit | bc_programming's commentslogin

"compare something like Swing's JTable to WinForms' DataGrid"

Do you actually mean the DataGrid? Because the WinForms "DataGrid" was deprecated in 2002 with .NET 2.0 which added the DataGridView. The software I work on is Windows Forms and I can't say I've had any issues like you describe with the DataGridView. I was able to create a control derived from it that does all the heavy lifting for customizations(Visual, interaction, cell spanning, etc.), of which we had a lot. Enough that we were exploring third party controls, but found we would have to customize those ourselves anyway, so I just wrote my own control based on DataGridView to save us the licensing.

WPF had it's own DataGrid control from the start, though I can't comment from experience on it's versatility, I'd assume given WPF's nested-content approach it is surely at least more flexible than the DataGridView.


Yes, I mean DataGrid. .NET 2.0 wasn't released until October 2005 so I think your remembrance of dates is a little bit off (understandable: it's now a long time ago).

In any case that didn't really matter. In mid-2004, when I started, the company was still targeting .NET 1.0 for all apps because it meant we could guarantee customers would have that runtime installed on their machines without the need for another dependency. The business model was download -> try -> buy so we wanted as little friction as possible and having a newer version of .NET that might require another download and install wasn't worth the dropout rate we'd experience.

That being said, .NET 1.0 also meant we were using Visual Studio.NET 2002 which was... incredibly painful to work with. I'd come from the world of IntelliJ IDEA which had all manner of code navigation, inspection, refactoring, and testing functionality built in. Not to mention Java already had generics and a much better and more comprehensive framework class library and more mature OSS scene covering whatever was missing from that. .NET 1.0 and VS2002 had none of it and, I forget, was it that VS2002 had no extension model or was it just that ReSharper didn't support it? Either way it felt like stepping back into the mid 1990s and I wasn't happy.

Eventually, sometime in summer or autumn of 2005, I managed to persuade leadership that at least allowing us to use .NET 1.1 and Visual Studio.NET 2003 would be a good idea, and would enable us to use ReSharper, which at least brought us on par with IntelliJ IDEA circa 2003 or so. I can't remember but it might have been that .NET 1.1 had been rolled out over Windows Update or enough service packs for Windows 2000 or Windows XP that we deemed the likely loss of purchases to be negligible.

Our first products developed with .NET 2.0 we didn't start working on until the back half of 2006 and this was really only because we were developing products that plugged in to SQL Server Management Studio which, again IIRC (long time ago), was based on the Visual Studio 2005 shell and required .NET 2.0.

We were always lagging on .NET versions because we wanted to make sure someone could just download, install, and run our products without needing to do anything else.


A pascal string is a single byte with the length, followed by the data.

Some implementations use more bytes for the length data, such as Delphi which changed over to a 4 byte prefix length, though those aren't technically Pascal strings anymore. I can't find anything about a Pascal string being two pointers?


It is conceivable, for both Pascal and C, to have more than one string implementation side by side, so the developer can choose to use the best-fitting one.

In C++23, variant<> permits to do what Rust's typed enums introduced (e.g. Result sum type that is either a "real" result - with result type - or an error - with error type -, each strongly typed).

If you do that, a definition like

  class IString { /* basic string functions */ };

  class MiniString : public IString {};
  class CZeroTerminatedString : public IString {};
  class PascalString : public IString {};
  class CppString : public IString {};

  use String = std::variant<MiniString, CZeroTerminatedString, PascalString, CppString>; // define one type for all impl.
permits to define string functions that operate over the sum type String, and which use the methods defined in the interface IString, and which then work for all string implementations.

The developer can then pick the most suitable implementation, i.e. CMiniString for very, very short strings (that fit into 64 bits, so approx. <= 8 UTF-8 characters), CZeroTerminatedString (for char *co = "test\n"; zero-terminated old style C strings), CPascalStrings for strings that carry a length in s[0] or as a struct member or class field, and CppString as a wrapper for the C++ std::string that implements IString.

Sum types are a type-safe and memory-preserving way to do what in the older days was sometimes implemented using a "union {}" (which was not type-safe).


Free Pascal strings (and i assume Delphi as they are sometimes compatible) are pointers to the first character of a null terminated string with a header in a negative offset before the first character indicating the string's length, reference count and codebase.

AFAIK a "Pascal string" is basically another way to say "length-prefixed string" (as opposed to null terminated string) and Free Pascal (and Delphi) are like that (and they're Pascal dialects too, so their strings are literally Pascal strings :-P).


My favourite example of "Modern" style is the toggle switch, shown even in that image. I laugh a lot of the times I see one, it's the 'replacement' for the checkbox, but it's so awful at actually telegraphing it's current state in a consistent way- (the entire purpose of the control!) that it has to have a label indicating whether it's on or off. I find it so absurd that people genuinely put this stuff into their programs and have no problem with it, because apparently we are just supposed to accept this type of poorly designed component because it's more "Modern".


But think of the poor users expecting consistency with their phones where confusion is expected!


We don't digest food exclusively with bacteria. They play a role, of course, but our digestion is done through things with hydrochloric acid and various enzymes produced by the stomach. The bacteria in our stomach is pretty much strains that can both survive the acidic environment and can consume things we cannot digest at all. Various fibers, for example. They help as they consume it and shit out stuff we can digest. Often the things they consume that are indigestible to us are the result of our own breakdown of other compounds; making the process symbiotic.

Also, the environment on a kitchen counter is wildly different than the environment inside out stomach, so airborne bacteria- even if we were to presume these were the exact same kinds of bacteria present in our stomach - being uninterested in foods in the open air doesn't really translate to the idea that the food is indigestible. Many gut bacteria rely on us to break down foods into the things that they can digest, so a colony couldn't start on the surface of the same food(s) in the open air.


Well if it's self-hosted you have to do it yourself. You can either backup your databases from the old version and restore it to the new version once installed, or you can use pg_upgrade to upgrade/copy a old version data directory to the new version.

I don't think this is done automatically when you simply install a new postgres version, but I'm not certain of that.


It's related because that past suggests a history of being untrustworthy. I mean we're talking about running a company that literally stole money from people and intentionally infected peoples computers to try to trick them into giving you more money, not just something he did by accident one weekend but something he dedicated years of his life to. Him leaning heavily on how he worked at a company two decades ago doesn't help. Other than the scam company shut down by washington state, what has he done since?

As for the particular claim regarding the start menu, What he actually claimed is that his implementation was removed in production builds. However, at the same time, there's no evidence of it in any of the various Beta and release candidate versions of NT4. Not only that, but prior to the NT4 betas, it was effectively the NT 3.51 "Desktop Shell Update" and none of the releases of that have his claimed implementation. So when and where is it?

He states "I wrote the programmatic version in '94 and we ran it internally". The issue is that there really was no "NT4 beta" at that point in time, nor any start menu in NT to add his rotated text code to. It was only around the start of 1994 that what would be known as the Taskbar and Start Menu really appeared in Chicago milestones- we know he isn't referring to those, since 9x didn't support the needed LOGFONT structures. What would become the start menu on Windows NT only appeared with the "Newshell" project which was preview software that you installed on NT 3.51 to add the Windows 95 enhanced shell. originally a desktop update for Windows NT 3.51 which started around the time of 95's release in, well, 1995. There's no evidence of his special code there- in fact the NT 3.51 Desktop Shell Update previews all used a bitmap.

And you might think, ahh, hew must mean before that, but the rotation feature in question, I believe, was new to NT4 altogether- so it would presumably have appeared somewhere during the betas.

The problem with his claims seems to be that evidence never seems particular forthcoming. When new information comes out he retracts claims and re-titles videos in order to move his claim into "gaps" where his claims are less falsifiable.


You seem to be of the opinion that people cannot learn from mistakes and cannot change and should not be given second (third? fourth?) chances to rehabilitate themselves and recover from bad decisions or habits?


This issue seems like partly an artifact of the invented binary operator ^. In math exponents are superscripts and there's no binary operator- it's part of the term. But for text on computers, binary operators ended up being fabricated for the things you couldn't represent directly. The caret is common and was the first one to appear, but doubled multiplication signs is another one. Traditionally, binary operators have lower precedence than unary operators since the unary minus is considered part of the term, so the exponent turning into an operator mucks things up if it's still implemented to adhere to that logic.

You sort of see the same issue with division. The forward slash is a completely invented binary operator since the actual division symbol was often not present- and let's be real nobody uses the binary division operator when writing formulae. It's supposed to represent the dividing line in a fraction, similar to how division is usually represented in a formula as a fraction of two other expressions. It's got lower precedence than anything in either term- but, if you just replace the dividing line with a forward slash to input the formula into a computer, you'll get incorrect results, because it's replacing what is part of a complete term (the division line) with a new binary operator inserted between sets of terms, which is now subject to precedence rules.


I suspect it's more likely an artifact of how the number is lexed. `-3^2` probably gets lexed into Number(-3), Operator(^), Number(2), which results in the aforementioned precedence issues. The reason for parsing the operator with the number is that it makes it easier to handle the case where you just write a negative number as a literal value into a cell.

Source: I've written an Excel clone before. I don't believe it has the same bug, but if it does, that will be how it's crept in.

EDIT: looking at some of the descriptions of the bug, it seems like it happens when handling variables (i.e. cell references) as well, which makes it seem like a pure precedence issue and not a parsing issue. So I've got no idea, presumably someone simply messed up the precedence order.


It's almost certainly a precedence issue. It's much easier to consider that unary operators have precedence over binary operators, and just learn the precedence rules for each class, rather than a global precedence rule. Plus, there's no conflict with math notation, as there is no exponentiation operator in math.


In my country we teach the same rules in math class. Blaming it on “unary vs binary” was a stretch. Next you’re going to blame it on the lexer for producing the -3 as a single term instead of two. (Which WOULD explain something, but… fix it?!)

In my country we use a horizontal line with a dot above and below to indicate in-line division in lower grades. Exactly like the computer /.

It’s not like there was no precedent here.


I also learned the line with a dot above and below in my country, the USA. But that was a very long time ago, math teaching has changed immeasurably since my time.

In Unicode it's U+00F7: https://www.compart.com/en/unicode/U+00F7


This is because a particular support page has "The Control Panel is in the process of being deprecated in favor of the Settings app, which offers a more modern and streamlined experience.". Crazy how that somehow has spawned endless articles from tech "news" sites. But it's hardly news, and saying they've 'officially deprecated' is misleading. Fact is The Control Panel has been in the 'process of being deprecated' since Windows 8.


For me, I bought "Clean Code" because it was, at the time at least, quite highly recommended. After being rather confused for a while, I finally stopped reading right around page 141 when I realized that the reason his examples looked awful were because they were.

In that section of the book, he takes a Java port of Donald Knuth's PrintPrimes program, and refactors it. But in doing so, he actually breaks it. He moves state out of local variables and parameters and makes them all static fields, and then refactors the code into long-winded methods that specifically perform side effects or operate on those fields (names like isNotMultipleOfAnyPreviousFactor(), isLeastRelevantMultipleOfNextLargerPrimeFactor()). But the simple act of moving state that would otherwise be part of the stack frame into static fields means he has changed the behaviour of the code - it is no longer thread safe! calling it from different threads will have undefined results because all threads will be operating on the static fields. He demonstrably made the code worse!.

It invalidated the entire book for me at that point. Here's "Uncle Bob" trying to pretend to be some aged, skilled, craftsman hand guiding us young, ignorant whippersnappers into being proper craftsman and not only can't he properly refactor a simple prime number sieve as a demonstration, but he's so blind to awful code that he doesn't even see it in his awful example enough that it gets published in the same book that complained about programmers who don't have "code-sense". Mistakes and "errata" are one thing, but when he makes such a big noise about "do it right the first time" and then has an example where he refactors and literally breaks something, that's another.


I started reading the code Martin wrote with his son for the “FitNesse” acceptance tracking framework.

The code was simply God awful. Nearly every method was tagged ad “throws Exception”, no comments, and the famous endless sea of classes with only a few lines of code per method.

The code itself ran with constant exceptions filling up the logs. This was going back over a decade or more when I looked at it.

You can see his lineage of trying to sell consulting services and books all the way back to the comp.object Usenet groups back in the 90s.

Sadly he still commands big fees to speak at various conferences and companies, I was very disappointed when he spoke at Bloomberg many years ago when I worked there.


Interestingly enough, John Ousterhout was a recently on Book Overflow podcast and he says he uses this very refactoring but on reverse to teach good software design. So it’s good for something!


In my opinion the only good part of that book is the title.


I even hate that the title got popularized. Code isn’t “clean” or “dirty”. It works or it doesn’t work. That’s the most important aspect. Another very important aspect is that It’s readable or unreadable. Readable code may be very long winded, but I would much rather have that than somebody’s idea of a “clean” concise very abstract piece of logic.

I hate when I get comments on a PR talking about some subjective piece of code suggesting an alternative that they think is “cleaner”. How clean a piece of code is shouldn’t be a part of consideration while reviewing any code. Instead, like I said before, the only thing that really matters is if it works and if it’s readable. I wonder how many junior engineers have been bogged down with pointless PR comments over the years because of this idea that code can somehow be “neat” or “clean”.


I always took it more as readable code.


I mean. It’s not like people pushing “side effects” (read: literally any change at all) aren’t also being overtly dogmatic, and writing utterly terrible code.

Uncle bobs book didn’t age well, but neither will the dogmatic stances on immutability and side effects.


In this case, By "side effects" I mean non-obvious changes to the static state, Where a seemingly simple function will both rely on static fields to evaluate it's result as well as make changes to various other fields that will subsequently change the result of that function going forward. I don't think one needs a dogmatic adherence to immutability and avoiding side effects to find that to be undesirable.


I agree. Just letting you know that, most likely, the people you are learning about “side effects” from don’t actually mean “side effect” in the colloquial sense of “state changes beyond the expectation”.

They mean literally any change at all. If your function is named addOne(&x), then they consider the result of x being one greater to be a “side effect”, whereas I suspect actually sane people such as yourself would not see that as a side effect.

This type of definition fuckery is one reason (among many), that I’ve come to fully disrespect functional programming communities.

One thing that also needs to be understood is that side effects (to your definition) are not explicitly bad things. Side effects ignoring boundaries, ignoring APIs, holding references, etc are probably mostly bad though.

In fact, in gaming, providing hooks to empower side effects is often explicitly good for granting designers mechanic freedom.


My belief is the people you are talking about think of programs as batch operations where you take data transform it and then pass it to someone else's API calls. In that case state is sort of evil.

In embedded and gaming state changes in response to input is the point of everything.


I'm one such person!

"Side effect" doesn't have any useful meaning if it doesn't have teeth.

Nothing is a side effect if it's what the programmer intended to do.


What's especially important is non-obvious state.

I was trying to use a function. You had to create an instance of it to use it, but I was using one method that by appearances should have been static. You feed it an input, it gives you an output, there's nothing to remember. I was calling it from multiple threads--occasional corruption. There must have been something being stored into the object but I have no idea what or why.


Avoiding side effects as much as possible is not a new idea, though; it's been around since at least the 80s. You can just ask people who have worked on Haskell code written in the past 25 years to determine for yourself if the idea aged well or poorly. Opinions will probably be mixed, though, not clearly one way or the other.


The definition of "side effect" has to mean something, otherwise it defaults to the opinion of whoever wrote the code.

  // Not a side-effect (intentional)
  if(++i++) {
  }


I don't understand how this relates to my comment. I'm saying that avoiding side effects isn't a new idea, so it already has aged, either well or poorly.


I don’t really care about the opinions of Haskell coders, as they are probably the only programmers on earth that have more terrible dogmatic ideals than uncle Bob does.


If you're open to challenging your preconceptions (dare I say dogma?) about Haskell programmers then I'm willing to share my opinions on good software development and how Haskell helps, based on over a decade of professional experience with Haskell. Free tidbit: I find effect tracking to be extremely beneficial to software engineering in the large.


Not quite what you are describing, but you can prevent any specific executable from ever running by configuring a "debugger" for it in Image File Execution options (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options). You add a key with the executable name and then add a "debugger" value, then point that debugger at C:\Windows\system32\systray.exe. Every time the named executable tries to launch, Windows will try to "debug" it with systray, which immediately exits so the program never actually runs. After uninstalling OneDrive this can be set to prevent OneDriveSetup.exe from ever running for example.


You can also define software restriction policies to do similar things.

It id what SRP's are for (but yes, I would not put it past them to disable anything targeting OneDrive).


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: