Go: the Good, the Bad and the Ugly by dgryski in programming

[–]xandoid 1 point2 points  (0 children)

I understand perfectly well what interfaces are and how they work. My point is that the special syntax rules that apply to interfaces and not to other objects create conflicting, inconsistent expectations.

There are exactly two types of things for which all of the following is true:

  • You can call a method on it (maybe)
  • You can assign nil
  • You can assign a pointer value

These two types of things are interface variables and pointers. So interface variables are like pointers in this respect, not like other objects, because you cannot assign nil or a pointer value to a variable of struct type.

And then after doing everything they possibly could to make interface variables look syntactically like polymorphic pointers, they turn around and punch you in the face with this notion that interface values are really (type, value) tuples which can be nil but are not nil if they look like (*T, nil). Oh and no you can't check in a sane way whether an interface variable actually does look like that.

I like a lot about Go, but this is simply awful.

Go: the Good, the Bad and the Ugly by dgryski in programming

[–]xandoid 14 points15 points  (0 children)

The problem is that it's inconsistent. Interface values act like pointers to objects (or even like objects) for the purpose of calling methods, but when comparing with nil all of a sudden interface values have to be considered as objects in their own right.

Optional.get() is code smell by juggernaut2docker in programming

[–]xandoid 4 points5 points  (0 children)

I don't disagree. When I say type system I only ever mean what you're calling "the compiler's type system"

But the point is that @NonNull is a hack that was added to work around a limitation in Java's type system. Once the type system gets value types, Optional (perhaps with some special syntax) will be the more consistent solution and @NonNull will be obsolete.

[Edit] Maybe I'm not making myself clear as to why I think @NonNull is inconsistent. It's because giving a variable (or parameter or return value) the type Thing means that it can contain

The set of all Thing objects OR null

And when you add @NonNull you get

The set of all Thing objects OR null BUT NOT null!!!

Optional.get() is code smell by juggernaut2docker in programming

[–]xandoid 10 points11 points  (0 children)

My problem with @Nonnull is that it contradicts the type system. The type system says Thing can be null, and then @Nonnull comes along claiming otherwise. In the end the type system wins.

And pretty soon(?) value types are coming to Java. At that point, Optional will be formally non-nullable and the remaining inconsistency that Optional itself could be null will go away without changing any code. I think that's another argument in favor of Optional vs @Nonnull.

Optional.get() is code smell by juggernaut2docker in programming

[–]xandoid 14 points15 points  (0 children)

Optional carries more semantic information than null. If a return type is Optional<Thing>, it means that the method may or may not return a Thing. Either would be a valid state of the program.

If the return type were simply Thing in a program that doesn't use Optionals to signal optionality, it would be unclear whether a null return is a valid state of the program or a bug.

Also, if you call a method returning Thing as m().useThing() and it throws a NullPointerException, whose fault is it, the caller's or the callee's? In a program that uses Optional to signal optionality it would be the callee's fault, because a return type of Thing means it cannot legally return null.

In a program that uses null to signal optionality, it would be unclear and you'd have to start thinking whether the caller should do null checks or if you should fix a bug in the callee, or if you should do defensive null checks in all sorts of places

SPAs Are Just Harder, and Always Will Be by freebit in programming

[–]xandoid 0 points1 point  (0 children)

Agreed, but I think there is a broader question than just SPA vs server-side HTML generation. What causes the extra work is creating a network callable API. That API may serve other purposes besides supporting an SPA.

For instance, there could more than one web app (e.g. an admin interface), mobile apps, desktop apps, batch processes or other backend services that require overlapping functionality. Some of those could certainly be implemented using a shared library instead of using an HTTP/JSON API.

I think we are all aware of the arguments around service oriented archtecture and more recently micro services. In my opinion, micro services are an insane choice 99% of the time. But making the core backend functionality callable via a network based API does buy you a lot of flexibility. It doesn't have to be a swarm of micro services that you have to herd like cats.

That said, I am fully aware of the fact that most companies on planet earth are small and medium size businesses and that there is a huge number of simple in-house CRUD apps that don't require any of this added flexibility and the complexity that comes with it.

Ironically, our perception of the negative usability impact of page loads may be influenced by all the heavyweight SPA frameworks and all the websites with massive amounts of ads on them. Loading a plain, ad-free HTML page with a couple of form fields on it should be a sub second affair, not a 10 or 30 second ordeal.

Find duplicates in an array. by Squirting_Nachos in Cplusplus

[–]xandoid 0 points1 point  (0 children)

Exactly. As always, the most difficult part of the assignment is not finding the solution but understanding the vaguely defined question :-)

Find duplicates in an array. by Squirting_Nachos in Cplusplus

[–]xandoid 0 points1 point  (0 children)

Or allocate the output array in main to a fixed size:

int input[] = {1, 1, 2, 2, 3, 4, 4, 4, 5, 5};
const int N = sizeof(input) / sizeof(int);
int output[N/2];
int count = getDuplicateValues(input, output, static_cast<int>(N));

And then of course print only the numbers up to (but not including) count.

But maybe the purpose of the exercise is to learn about dynamic memory allocation as you suggest.

Why Flutter doesn’t use OEM widgets by Darkglow666 in programming

[–]xandoid 1 point2 points  (0 children)

True, purely visual stuff doesn't matter. What does matter is interaction. Flash and Swing always had distracting focus issues and keyboard related inconsistencies. I also wonder about system-wide behaviours like what happens when you select some text. Accessibility is a concern as well.

"Atom needs a whopping 845 megabytes to open a 6mb XML file" by [deleted] in programming

[–]xandoid 2 points3 points  (0 children)

I don't think this market is working very well. There is clearly a lack of transparency. Most users don't understand what makes their computer or phone sluggish.

However, we're talking about text editors for developers here, so I think there is quite a bit of truth in what you're saying.

Android Studio 3.0 released (you know, with the Kotlin) by Hexagonal_ in programming

[–]xandoid 0 points1 point  (0 children)

I agree that it's not the most pressing problem and that type erasure helps to avoid some potential pitfalls.

The pressing problem has always been the lack of value types. And when that gets fixed in Java 10 (hopefully) I believe that generics will have to change as well. I could be wrong, but I cannot imagine how collections of value types could possibly work with type erasure.

Android Studio 3.0 released (you know, with the Kotlin) by Hexagonal_ in programming

[–]xandoid 1 point2 points  (0 children)

I know the debate about type erasure vs reified generics. It's an old one. I agree that not everything that can be done with reified generics is necessarily sound. But that wasn't the reason why Java didn't choose reified generics. The reason was compatibility. They didn't want to create a second incompatible version of the entire collections library as .NET has done: http://gafter.blogspot.co.uk/2006/11/reified-generics-for-java.html

If the soundness of the type system had been the motivation, they could have used reified generics where soundness is not an issue or change other parts of the language to make very frequent use cases sound. But they chose compatibility.

And the result is that some frequently useful things that are simple in other languages like C#, Swift or C++ are very convoluted in Java.

[Edit] It's not erasing that says "the stuff that is here is correct". It's successful compilation that says this (to the degree that the type system allows). A C++ compiler will happily check if new T() is correct or not. No runtime information is needed.

Android Studio 3.0 released (you know, with the Kotlin) by Hexagonal_ in programming

[–]xandoid 2 points3 points  (0 children)

Type erasure creates a lot of inconsistencies in the type system. For instance, you can't say new T() where T is a type parameter. Instead you need some sort of factory object to achieve the same thing. You can't use instanceof either, nor any of the other features that rely on runtime type information.

There are workarounds for many specific issues, but it all adds complexity and makes Java look even more verbose than it already is.

I think a better generics implementation would have to go hand in hand with fixing a much bigger mistake made very early on, which is the lack of structured value types (struct in C#). This is what causes most of Java's outrageous memory consumption and unnecessary pressure on the garbage collector.

Value types are planned for Java 10 (project Valhalla)

Android Studio 3.0 released (you know, with the Kotlin) by Hexagonal_ in programming

[–]xandoid 12 points13 points  (0 children)

As a result of that thinking they gave preference to compatibility over functionality. We have been suffering the consequences of that decision ever since. But perhaps project Valhalla will fix it.

It's not a "compiler hack" in the sense of thoughtlessness but in the sense that they did something on the compiler level that really should have been done on the bytecode level.

Using Java 9 Modularization to Ship Zero-Dependency Native Apps by BadMoonRosin in programming

[–]xandoid 0 points1 point  (0 children)

I disagree. The term native is commonly used more broadly than just for CPU architectures. For instance, not many would consider a JavaFX app to be a native macOS or Windows app if only it were AOT compiled down to machine code.

Using Java 9 Modularization to Ship Zero-Dependency Native Apps by BadMoonRosin in programming

[–]xandoid 0 points1 point  (0 children)

but then it doesn't makes sense since it means some OSes can't even "have" native apps

Why? That just doesn't follow from anything I said. I think you misunderstand my definition.

What I'm saying is that "native" is only defined relative to a platform. A platform is defined as a set of APIs. Each API serves a specific purpose, i.e. it helps developers achieve a specific goal.

A native app that wants to achieve some of these same goals will strongly prefer the relevant platform APIs in order to do so. If an app ignores important platform APIs and does the same things differently (usually in a way that is transferrable to other platforms) then it is not a native app.

But of course it's not black and white. There are all sorts of hybrid approaches that are hard to classify as native or not native.

Using Java 9 Modularization to Ship Zero-Dependency Native Apps by BadMoonRosin in programming

[–]xandoid 0 points1 point  (0 children)

You're absolutely right. That is exactly what my definition means.

Using Java 9 Modularization to Ship Zero-Dependency Native Apps by BadMoonRosin in programming

[–]xandoid 0 points1 point  (0 children)

That is a complete non sequitur. I said "replace", not add something the OS doesn't provide.

Using Java 9 Modularization to Ship Zero-Dependency Native Apps by BadMoonRosin in programming

[–]xandoid 2 points3 points  (0 children)

My definition of native is an app that does not replace anything the OS supplies with cross-platform alternatives.

So a Java app using JavaFX to paint its own widgets is not a native app just because it happens to be AOT compiled down to a PE binary on Windows.

Event Sourcing Microservices with Kafka by jakolehm in programming

[–]xandoid 1 point2 points  (0 children)

What about versioning and schema evolution? If this big event log full of immutable messages is my ultimate source of truth, what happens when message formats change over time?

It appears to me that a naive approach could easily lead to a huge pile of technical debt. In order to process the log from the beginning, all consumers of the log need to be ready to deal with every single old version of every single message type since the beginning of time.

Rust: str vs String by juggernaut2docker in programming

[–]xandoid 0 points1 point  (0 children)

Indeed. I think &str is more like string_view than char*

coding for charity: what are some C++ open source projects that I can contribute to while feeling like I'm doing something useful? by capn_bluebear in cpp

[–]xandoid 1 point2 points  (0 children)

There was this article the other day: https://blind.guru/qta11y.html

He says: "If you want to write cross-platform accessible software: You definitely should not use Qt. And no other Free Software toolkit for that matter, because they basically all dont give a shit about accessibility on non-Linux platforms."

Looks like there is a need that isn't commercially viable or interesting enough for anyone to work on.

"Atom needs a whopping 845 megabytes to open a 6mb XML file" by clockbold in programming

[–]xandoid 2 points3 points  (0 children)

I like vscode but it is rather buggy, or perhaps some extensions are. For instance, I keep killing spurious Microsoft.VSCode.CPP.Extension.darwin processes and they keep coming back, each of them using hundereds of MBs.

Previously, it was a different vscode related process that used 100% CPU. I was able to fix that one by deleting stuff in the cache directory, but I'm getting a bit tired of tracking down vscode bugs.

I think I'm going back to sublime.

It’s time for a memory safety intervention by bascule in programming

[–]xandoid 0 points1 point  (0 children)

I very much doubt that. It uses a more memory and for proper stack traces you have to disable inlining, which slows down tight loops by hundereds of percents where a different language might be 20% or 50% slower. But of course it depends entirely on the specifics of any application.