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
dougdrums
Feb 25, 2005
CLIENT REQUESTED ELECTRONIC FUNDING RECEIPT (FUNDS NOW)

Thermopyle posted:

Java isn't really notably slow (depends on what/how you're comparing, of course),

This is relatively old but you reminded me of the quote:

quote:

The plain truth is: Java is slow. Java isn’t just slow, it’s really slow, surprisingly slow. It is “you get to watch the buttons being drawn on your toolbar” slow.
Why are we using Java again? (Sorry about paywall :()

I read it in another paper that talked about JIT compilers. Pre-gnu-lightning Smalltalk wasn't spared either.

dougdrums fucked around with this message at 19:01 on Aug 16, 2016

Adbot
ADBOT LOVES YOU

Volguus
Mar 3, 2009

feedmegin posted:

Doesn't help with the complaint about reading the code though. Plus, to my mind a language that requires an IDE to generate massive chunks of code for you to be usable is not a very good language.

You'd hate C++ then. Or, not to mention, C.

Scala ... eh, is an interesting language, but when reading some gibberish code and then trying to google for it to see WTF is that thing doing and the search returns no results, what does that say about that language then? And about the IDE hate: what year are you living in? Without syntax coloring or some modicum of autocompletion or at least helpers and hints every now and then ... it sucks, doesn't matter the language. I wrote code in Turbo C++ on a monochrome monitor back in early 90s, I don't wanna do that again.

Absurd Alhazred
Mar 27, 2010

by Athanatos
I'm not getting into specifics, but any time I try to do something new using the Windows API, I feel like it's been written by a hardware vendor.

It's 2016, you're the ones promoting C++ at the least, or C#/managed code more often than not; why the hell does your API read and write through pointers, giving me obtuse handles connecting to system objects I then have to keep around as parameters for future system calls?

I frequently find myself scouring github for dumb wrapper/multiplatform classes with MIT license or the boost library to avoid dealing with what should be straightforward for someone writing Microsoft Windows code in Microsoft Visual Studio.

Ellie Crabcakes
Feb 1, 2008

Stop emailing my boyfriend Gay Crungus

TooMuchAbstraction posted:

Java's big problem is with verbosity.
It's biggest problem is Java Programmers.

raminasi
Jan 25, 2005

a last drink with no ice

Absurd Alhazred posted:

I'm not getting into specifics, but any time I try to do something new using the Windows API, I feel like it's been written by a hardware vendor.

It's 2016, you're the ones promoting C++ at the least, or C#/managed code more often than not; why the hell does your API read and write through pointers, giving me obtuse handles connecting to system objects I then have to keep around as parameters for future system calls?

I frequently find myself scouring github for dumb wrapper/multiplatform classes with MIT license or the boost library to avoid dealing with what should be straightforward for someone writing Microsoft Windows code in Microsoft Visual Studio.

Because it's old as gently caress. (I'm assuming you're not talking about WinRT.)

Absurd Alhazred
Mar 27, 2010

by Athanatos

raminasi posted:

Because it's old as gently caress. (I'm assuming you're not talking about WinRT.)

Windows 7+ is about 7 years old. That's not old as gently caress. Java, which as a language is old as gently caress, already had object-based APIs throughout pretty much since its inception.

Kazinsal
Dec 13, 2011


A lot of Windows' API has been unchanged for a distressing number of years. I mean, take a look at the Hello World example from the Windows SDK circa 1985 and tell me how many functions you recognize...

http://www.charlespetzold.com/blog/2014/12/The-Infamous-Windows-Hello-World-Program.html

FrantzX
Jan 28, 2007

Kazinsal posted:

A lot of Windows' API has been unchanged for a distressing number of years. I mean, take a look at the Hello World example from the Windows SDK circa 1985 and tell me how many functions you recognize...

http://www.charlespetzold.com/blog/2014/12/The-Infamous-Windows-Hello-World-Program.html

You know, there's a 50/50 chance that you can compile and run that exact code.

comedyblissoption
Mar 15, 2006

Volguus posted:

There are, yes, numerous verbosity complaints about Java, but the IDEs have largely fixed all/most of them.
Generating giant amounts of boilerplate w/ an IDE doesn't fix having to read that giant amount of boilerplate later. Readability is a far more important trait of a language than writability.

C# is a good example of a Java w/ much less boilerplate, although C# still has a lot of flaws IMO around verbosity.

raminasi
Jan 25, 2005

a last drink with no ice

Absurd Alhazred posted:

Windows 7+ is about 7 years old. That's not old as gently caress. Java, which as a language is old as gently caress, already had object-based APIs throughout pretty much since its inception.

The API I presume you are complaining about is basically Windows 95-era. They don't re-do it with every Windows release. There are newer APIs (.NET, or WinRT) but you're not using them for some reason.

brap
Aug 23, 2004

Grimey Drawer
That feel when a language requires implementing gethashcode whenever you want to implement equals

vOv
Feb 8, 2014

I still want to know why Java's URL.equals does DNS lookup on the domains.

Xarn
Jun 26, 2015

fleshweasel posted:

That feel when a language requires implementing gethashcode whenever you want to implement equals

Yeah, thats dumb as gently caress, but lets be honest - the entire idea of gethashcode method is wrong and dumb.

vOv posted:

I still want to know why Java's URL.equals does DNS lookup on the domains.

"It seemed like a good idea at the time." I guess. Someone probably wanted to get absolutely canonical answer and didn't think too hard about the tradeoffs.

vOv
Feb 8, 2014

fleshweasel posted:

That feel when a language requires implementing gethashcode whenever you want to implement equals


Xarn posted:

Yeah, thats dumb as gently caress, but lets be honest - the entire idea of gethashcode method is wrong and dumb.

Having never used C# in anger, what's wrong with this?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
You have to implement an entirely irrelevant method just because of the off-chance that someone might put an instance of your class in a hashtable.

On the other hand, knowing that you can put any arbitrary object into a hashtable is actually pretty darn useful.

LOOK I AM A TURTLE
May 22, 2003

"I'm actually a tortoise."
Grimey Drawer

Jabor posted:

You have to implement an entirely irrelevant method just because of the off-chance that someone might put an instance of your class in a hashtable.

On the other hand, knowing that you can put any arbitrary object into a hashtable is actually pretty darn useful.

Honestly it was a mistake for Equals and GetHashCode to be defined on System.Object. Lots of classes have no notion of equality and should never even be compared to each other, let alone be used as keys in hashtables, but because every object has Equals and GetHashCode the compiler will never tell you that you're probably making a mistake if you try to do it. IMO there should've been something like an IHashable interface, and Dictionary<TKey, TValue> should've been constrained to only work with keys that implement IHashable. Similarly it should only be possible to compare objects for equality if they implement IEquatable<T> or with some custom method. Of course you can always use object.ReferenceEquals(a, b) if what you want is reference equality, but in my experience it almost never is.

Haskell gets this right. If you want to compare objects using the == operator you have to derive the Eq typeclass, and for types with members that themselves don't implement Eq (e.g. functions) it's usually impossible to define Eq in a consistent way, so you'll never get this wrong unless you really go out of your way. For types that do have a proper notion of equality you can just write deriving (Eq) after the type definition and it will give you what you want 9/10 times, which is structural equality.

While we're on the subject, even ToString shouldn't have been defined on System.Object. Not all types can be converted to strings in a satisfactory way, and the default ToString implementation that just returns "[ClassName]" is virtually useless anyway.

I guess all of these things are mistakes .NET inherited from Java.

Xarn
Jun 26, 2015

vOv posted:

Having never used C# in anger, what's wrong with this?

It places the responsibility for hashing at the wrong place, especially if you have a non-trivial object. If you are implementing a String (or generally a container of primitives), you can easily look up a good hash function and implement it for the type, but its still something that shouldn't have to be done more than once. If you are implementing a non-trivial class, even something that only contains a pair of strings, then you have to somehow magically merge the hashes without sacrificing quality of the hash. This is basically crossing your fingers, while praying to your favourite computer deity.

It also makes it really loving hard to test how performant different hashes are for your application, or deciding to use a different hash for this purpose. (IE you found out that in this specific place the application is hashing a fuckload of strings, but you know that they have some specific property -- ie they all have 16 characters, or are distinct on a prefix/suffix etc)


The proper way to do all this would be to take a look at the usual hashes and recognize that almost without an exception* operate in 3 phases
1) Initialize the hash state. ie for SHA 256 this means init the initial hash and prepare constants for hashing rounds
2) Eat raw data in chunks. ie SHA 256 takes the input data in 512 bits chunks
3) Transform internal state to the actual output hash

If you create a hash object, phase 1 is the object constructor. Phase 2 could be a bit problematic in languages which don't let you access raw bytes, but probably could be solved by fuckload of overloads like
code:
add_data(int);
add_data(int[] data);
add_data(long);
add_data(long[] data);
...
and some internal buffering.

Phase 3 is a trivial method to implement.

getHashCode() is then transformed into addDataToHash(Hasher) and hashing non-trivial objects becomes easy -> you just pass given Hasher to members.

* I know of one, but I don't claim to know every obscure hash ever invented.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
There are lots of unequatable objects that you often want to put into a hashtable though, based on object identity rather than some sort of equality test. Which is where the motivation for having these methods defined on object comes from. Object identity of subcomponents is also often used when it comes to comparing equality for other complex objects.

Of course with the benefit of hindsight, it might have been better to have something like a HashComparator, with a platform-provided implementation based on object identity.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
If you don't want to support putting your object in Dictionaries why not write a GetHashCode that throws?

I got curious so I did a search, and Microsoft's documentation explicitly says:

"The GetHashCode method should not throw exceptions."

... But why not?

LOOK I AM A TURTLE
May 22, 2003

"I'm actually a tortoise."
Grimey Drawer

Jabor posted:

There are lots of unequatable objects that you often want to put into a hashtable though, based on object identity rather than some sort of equality test. Which is where the motivation for having these methods defined on object comes from. Object identity of subcomponents is also often used when it comes to comparing equality for other complex objects.

Of course with the benefit of hindsight, it might have been better to have something like a HashComparator, with a platform-provided implementation based on object identity.

I'm personally not very comfortable comparing or hashing based on object identity because I find it takes so little for someone to accidentally create a new instance with the same values somewhere and subtly break everything, but YMMV.

If you really need to do this I'd want you to have to do something like this:

C# code:
public class UncomparableType : IHashable
{
	public int GetHashCode() => object.GetStandardHashCode(this);
}

Bonfire Lit
Jul 9, 2008

If you're one of the sinners who caused this please unfriend me now.

FrantzX posted:

You know, there's a 50/50 chance that you can compile and run that exact code.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

LOOK I AM A TURTLE posted:

I'm personally not very comfortable comparing or hashing based on object identity because I find it takes so little for someone to accidentally create a new instance with the same values somewhere and subtly break everything, but YMMV.

If you really need to do this I'd want you to have to do something like this:

C# code:
public class UncomparableType : IHashable
{
	public int GetHashCode() => object.GetStandardHashCode(this);
}

Consider things like wiring up components with an event registration model - when everything (by default) can just go into an identity-based hashtable, you can implement listener registration pretty trivially, and can easily look them up again to deregister them. Otherwise, you need to do wacky stuff like iterating over every single listener to find the one being removed, or creating synthetic keys that the listener needs to hang on to in order to deregister later.

Fat classes like UI widgets don't generally override equality, but benefit a lot from an identity-based hashcode.

LOOK I AM A TURTLE
May 22, 2003

"I'm actually a tortoise."
Grimey Drawer

Jabor posted:

Consider things like wiring up components with an event registration model - when everything (by default) can just go into an identity-based hashtable, you can implement listener registration pretty trivially, and can easily look them up again to deregister them. Otherwise, you need to do wacky stuff like iterating over every single listener to find the one being removed, or creating synthetic keys that the listener needs to hang on to in order to deregister later.

Fat classes like UI widgets don't generally override equality, but benefit a lot from an identity-based hashcode.

Fair enough. For such cases you could have a subclass of Dictionary that implicitly uses the default implementation.
C# code:
public abstract class DictionaryBase<TKey, TValue>
{
	protected abstract int GetHashCode(TKey key);
}

public class Dictionary<TKey, TValue> : DictionaryBase<TKey, TValue> where TKey : IHashable
{
	protected override int GetHashCode(TKey key) => key.GetHashCode();
}

public class IdentityDictionary<TKey, TValue> : DictionaryBase<TKey, TValue>
{
	protected override int GetHashCode(TKey key) => (key as IHashable)?.GetHashCode() ?? object.GetDefaultHashCode(key);
}
In Haskell you often get pairs of functions where one is called "whatever" and the other "whateverBy". The whatever function only works on types that are part of some typeclass, while whateverBy requires you to provide your own one-off function that does the same job. Here's an example:
code:
maximumBy :: (a -> a -> Ordering) -> [a] -> a
maximumBy cmp list = *uses cmp to find the largest element in list*

maximum :: Ord a => [a] -> a
maximum = maximumBy compare
Basically I just don't like the idea of all objects being implicitly comparable and/or hashable. Clearly it's convenient sometimes, but I think it's also the cause of a lot of tricky bugs.

Edit: DictionaryBase can't be internal in my example obviously

LOOK I AM A TURTLE fucked around with this message at 10:23 on Aug 17, 2016

feedmegin
Jul 30, 2008

Volguus posted:

You'd hate C++ then. Or, not to mention, C. .

My day job is writing C++ and it doesn't involve an IDE generating anything, nor is the codebase I work in excessively verbose. Why would you think it did?

toiletbrush
May 17, 2010
I don't know who the horror is here, but...

We've got a client who wants SSO between their ecommerce site and ours, but they don't have the experience or time to build an identity provider - so we've built a temporary solution that's kinda hacky, but basically works - we redirect to them to log in, they redirect back to us with a short lived 'login' token.

So we had a bug where a user would be logged in on their side, but not on ours. You'd be on our site, on a logged out page, all is good. But sometimes, without clicking any links, you'd refresh the page and suddenly be logged in.

So I opened the network pane in Chrome - no traffic to the other side...but sometimes still logged in after refreshing the page. Caching? Nope...nothing. Cookies? Nope...nothing.

So I opened fiddler - and every now and then there's a request to their site's login-redirect-thing - bingo! But where's it coming from, and why doesn't it show up in the network pane in Chrome? Can't find anything in our Angular code. So when exactly does the request happen? Hovering over links...nope, nothing. Clicking links...nope, nothing.

So then I type in the url of a logged-in page in the address bar...bingo! There's the request to their side. WTF...

Long, tedious story short it turns out that Chrome pre-fetches pages when you type their url in the address bar, before you even press enter, and not only that, it executes javascript linked from that resource! So just typing in the url of a logged-in page would, behind the scenes, cause Chrome to go off, fetch the page, execute javascript, and set cookies...before you even pressed enter.

gently caress me.

As an aside, it appears Chrome doesn't even send pre-fetch headers anymore, so it's harder to protect your site against it.

Volguus
Mar 3, 2009

feedmegin posted:

My day job is writing C++ and it doesn't involve an IDE generating anything, nor is the codebase I work in excessively verbose. Why would you think it did?

If you think that Java is more verbose than C++, well, I don't know what to say. Though, is it true, code generation in C++ from an IDE is even now in infancy, compared to Java/C#, so you can't do that even if you wanted to.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

toiletbrush posted:

Long, tedious story short it turns out that Chrome pre-fetches pages when you type their url in the address bar, before you even press enter, and not only that, it executes javascript linked from that resource! So just typing in the url of a logged-in page would, behind the scenes, cause Chrome to go off, fetch the page, execute javascript, and set cookies...before you even pressed enter.

That's bonkers, but how did this issue get noticed in the first place? Do your testers go around typing stuff into the address bar without actually going to the page, just in case it has an effect? That's some comprehensive testing. I don't understand how it got picked up in the first place, unless there are other circumstances in which Chrome does this prefetching.

What does Chrome do in failure cases? For example what does it do if the prefetched JavaScript goes into a loop?

leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.

Volguus posted:

If you think that Java is more verbose than C++, well, I don't know what to say. Though, is it true, code generation in C++ from an IDE is even now in infancy, compared to Java/C#, so you can't do that even if you wanted to.

Lolwhatareyouonabout.

Java doesn't even have variadic templates.


e:
void iSeeYourPoint() {
}
void iSeeYourPoint(int this) {
}
void iSeeYourPoint(int this, int is) {
}
void iSeeYourPoint(int this, int is, int clearly) {
}
void iSeeYourPoint(int this, int is, int clearly, int less) {
}
void iSeeYourPoint(int this, int is, int clearly, int less, int verbose) {
}

leper khan fucked around with this message at 13:24 on Aug 17, 2016

OddObserver
Apr 3, 2009

raminasi posted:

The API I presume you are complaining about is basically Windows 95-era. They don't re-do it with every Windows release. There are newer APIs (.NET, or WinRT) but you're not using them for some reason.

And isn't the Win95-era API is a 32-bit cleaned up variant of Windows 3.x-era API?

toiletbrush
May 17, 2010

Hammerite posted:

That's bonkers, but how did this issue get noticed in the first place? Do your testers go around typing stuff into the address bar without actually going to the page, just in case it has an effect? That's some comprehensive testing. I don't understand how it got picked up in the first place, unless there are other circumstances in which Chrome does this prefetching.

What does Chrome do in failure cases? For example what does it do if the prefetched JavaScript goes into a loop?
I was just testing that redirection from logged-in pages was working, but used a logged-out page bookmark to start the test, and then type the logged-in url in. I noticed I'd get logged in without seeing the bounce between sites, wanted to figure out how and ended up going down a bit of a rabbit hole.

toiletbrush fucked around with this message at 13:47 on Aug 17, 2016

nielsm
Jun 1, 2009



OddObserver posted:

And isn't the Win95-era API is a 32-bit cleaned up variant of Windows 3.x-era API?

Kind of. It removes a lot of the near/far call weirdnesses, affects string handling somewhat (I assume), but on the other hand introduces most of the Win32 stuff from NT with synchronization objects and kernel handles.

Volguus
Mar 3, 2009

leper khan posted:

Lolwhatareyouonabout.

Java doesn't even have variadic templates.


e:
void iSeeYourPoint() {
}
void iSeeYourPoint(int this) {
}
void iSeeYourPoint(int this, int is) {
}
void iSeeYourPoint(int this, int is, int clearly) {
}
void iSeeYourPoint(int this, int is, int clearly, int less) {
}
void iSeeYourPoint(int this, int is, int clearly, int less, int verbose) {
}

It doesn't have variadic templates, but it does have variable arguments:

void iSeeYourPoint(int... noneedfor100methods) {
}

NihilCredo
Jun 6, 2011

iram omni possibili modo preme:
plus una illa te diffamabit, quam multæ virtutes commendabunt

Speaking of Java boilerplate, am I the only one who sees this as a coding horror?

PT6A
Jan 5, 2006

Public school teachers are callous dictators who won't lift a finger to stop children from peeing in my plane

leper khan posted:

Lolwhatareyouonabout.

Java doesn't even have variadic templates.


e:
void iSeeYourPoint() {
}
void iSeeYourPoint(int this) {
}
void iSeeYourPoint(int this, int is) {
}
void iSeeYourPoint(int this, int is, int clearly) {
}
void iSeeYourPoint(int this, int is, int clearly, int less) {
}
void iSeeYourPoint(int this, int is, int clearly, int less, int verbose) {
}

It depends; if there's a method, or especially a constructor, that takes a whole bunch of arguments and can take different sets of arguments, I'm pretty okay with having the actual signatures available, so the IDE can remind me what the gently caress I'm supposed to put in there and in which order, and also so that the argument types are statically checked. It's a little verbose, yes, but I don't think it ends up being worse code as a result.

CPColin
Sep 9, 2003

Big ol' smile.

No.

spiritual bypass
Feb 19, 2008

Grimey Drawer

Am I the only one who views @autowired as a horror?

VikingofRock
Aug 24, 2008




Does Java have auto yet? That made C++11 much less verbose IMO.

Volguus
Mar 3, 2009

I hope not. That's simply stupid.If it contains "extreme" in the name ... its probably safe to not follow.

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?

Haha, it's like people are coming full circle on OOP. They're almost back to it being plain functions. This here looks to be basically functions with closures implemented with classes.

Adbot
ADBOT LOVES YOU

hobbesmaster
Jan 28, 2008


Has he never heard of Scala or something? He mentions functional programming in the post so he obviously knows the phrase, but doesn't recognize what hes trying to do?

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