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
1337JiveTurkey
Feb 17, 2005

MOOMIN.EXE posted:

one of the developers at my jorb used to insist on doing seperate commits on every single file he modified

My last SVN commit was number 524193. :suicide:

Adbot
ADBOT LOVES YOU

1337JiveTurkey
Feb 17, 2005

TRex EaterofCars posted:

Also, if your server has been compromised to the point that an attacker can examine the memory space of your running JVM then they probably already have root and you are hosed anyhow.

Either that or you've got the remote debugger port enabled on a production system.

1337JiveTurkey
Feb 17, 2005

MEAT TREAT posted:

I think that falls under the you are hosed anyhow.

It also fits the spirit of the thread quite nicely, especially if you open a port in the corporate firewall to allow remote debugging after hours.

1337JiveTurkey
Feb 17, 2005

Check out the comments if you want to see the point of that class practically in orbit over some people's heads.

1337JiveTurkey
Feb 17, 2005

Plorkyeran posted:

The volatile there is extra-weird.

Just a wild guess, but the user might have ripped it off from somewhere else where it makes sense and didn't bother to remove it. The status registers for a UART in an embedded system would be some horrible combination of a volatile union and structs.

1337JiveTurkey
Feb 17, 2005

The == PHP operator really encourages what I feel is the dark side of dynamically typed programming languages. There's a big difference between a string of characters and whatever number it can be parsed as. The ability to make these sorts of conversions automatically can be a big timesaver but it's semantically sloppy or outright nonsensical.

A related problem is that identity is not the same as equality so the "safe" alternative isn't really. The only time it's really safe to assume that is when there's tightly controlled instantiation. Language-enforced singletons or OS handles for instance. But in the general case (especially with mutable state) it's at best an approximation.

1337JiveTurkey
Feb 17, 2005

tef posted:

implicit casts are a feature of weakly typed languages, not necessarily or exclusively within dynamic languages.

C has quite a few implicit casts

Dynamic languages tend to feature implicit casts on a broader scale than statically typed languages and with fewer compile-time sanity checks. The C type system is still too weak for my tastes but I feel it's in a different league from PHP. An implicit cast from one numeric type to a longer type is generally safe except for signedness issues and overflow. Honestly those two would be no problem if more languages took after Ada (no, really) and allowed trapping integer overflow or modular numeric types for where it's actually necessary.

shrughes posted:

Implicit casts are the same thing as inheritance.

Implicit casts are functions from one type to another. If I write foo = 2 + "2" or foo = "2" + 2 then depending on the language, foo might equal 4 or "22" (or both depending on the order of the operands). Either I'm terrible at math or that is the worst violation of the Liskov Substitution Principle I have ever seen.

1337JiveTurkey
Feb 17, 2005

nielsm posted:

I guess I see the logic. It just doesn't seem like a terribly useful mental model to me, though it surely can be useful in some formal proof situations.

Any place where infinitely many degenerate types serves as a useful model is equivalent to a typeless one. Literally every function becomes a cast from one type to another. It's frankly pointless.

1337JiveTurkey
Feb 17, 2005

Goat Bastard posted:

I wish I had a dollar for every time I've had to explain to a senior developer that the order of a result set is undefined unless the query has an ORDER BY clause

Varrays and pipelined functions called through the table operator without any subsequent joins in Oracle should be in order. At least I hope they are since I just ended up writing a query which relies on that to avoid generating a crapload of extra data just so I could sort it. :ohdear:

1337JiveTurkey
Feb 17, 2005

Internet Janitor posted:

Cloneable is fundamentally a problem because Object.clone() Doesn't specify deep or shallow copy semantics.

edit: No, we are not having a "mutable state is a horror" rant.

Object.clone() has the additional feature that it does return a new instance of the object being cloned but no constructor is ever actually called. So if your constructor is modifying some non-local state like a static variable, then the clone method needs to as well. Remember, this still applies even if your class isn't Cloneable itself since if it's not final someone can make a Cloneable subclass.

If your constructor is calculating something to set a final field, then you're just out of luck. Copy constructors are probably the best solution in that case.

Cloning mutable objects as an alternative to creating new copies of immutable objects really feels like it's doing the same work in the end. So as a matter of practice I default to making things immutable and can't remember the last time I've cloned anything.

1337JiveTurkey
Feb 17, 2005

nielsm posted:

But apparently C# Struct var; is equivalent to something like:
char buffer[sizeof(Struct)];
Struct &var = *(Struct*)(void*)buffer;


In C# a struct is a value type so it's local to the activation record or the object declaring it. That's the same as how it works in C except it's impossible to make a reference or pointer to a struct. So if you declare a struct in a method it's really just allocating the space on the stack right there.

edit: For what it's worth this is exactly what C++ is doing with objects and why it's always initializing the value to something. CLR/JVM/Objective C simply decided that this wasn't worth the attendant pain and made objects always heap allocated every time.

1337JiveTurkey fucked around with this message at 20:35 on Sep 26, 2011

1337JiveTurkey
Feb 17, 2005

GrumpyDoctor posted:

What? You can totally make a pointer to a struct. (In C, yeah, no references, but you can't make references to anything in C because they don't exist.)

OK, you can make pointers to anything and everything using unsafe code. I was more going for the idea that there's no safe way to have two pieces of code point to the same struct, just a reference type which has the struct as a value. Making pointers to the interior of an object or to the stack are generally recipes for trouble and that's exactly what the data model is trying to preclude with the value/reference distinction.

1337JiveTurkey
Feb 17, 2005

Brain Candy posted:

Object.clone() is basically just an alias for memcpy.http://ideone.com/LVj2Z

Lovely! I like in particular how the original instance can't get garbage collected until the clone does.

1337JiveTurkey
Feb 17, 2005

Che Delilas posted:

It's a high enough priority to write and release, but not high enough to test or change. Sounds like Microsoft to me.

Clearly this would not be a problem if every avatar were a Silverlight plugin.

1337JiveTurkey
Feb 17, 2005

OriginalPseudonym posted:

Which is not to say "Copy paste 110,000 lines of code, splice them together, and call it a day". There's reinventing the wheel, and then there's gluing together a full-sized car out of micro machines with spunk and used gum.

I'm more used to the crushing a luxury car into a vaguely wheel shaped object paradigm.

1337JiveTurkey
Feb 17, 2005

General Olloth posted:

It was obfuscated, I have no idea what it was called or what its purpose is, but I can't think of basically any good reason.

For confusing people looking at decompiled code, perhaps. At runtime it's just going to be inlined (JIT allows inlining of virtual methods with only one implementation in practice) and then eliminated entirely. So performance-wise, it's pretty close to zero cost and there's a definite nonzero cost for anyone trying to decompile and understand the code. I haven't messed around with obfuscators enough to tell if that's something commonly done, but there's nothing technically preventing it.

1337JiveTurkey
Feb 17, 2005

TasteMyHouse posted:

the thing I ran into a lot was attempting to overload on instantiated generic types -- you can't have a function that overloads different behaviors on a ArrayList<Foo> vs. an ArrayList<Bar> because they have the same erasure.

Just give the methods different names if they have different parameters. In this case having the information at runtime still wouldn't help because overloaded and static methods are always resolved with the declared types at compile time.

1337JiveTurkey
Feb 17, 2005

TasteMyHouse posted:

doesn't work with ctors :P

Try a static factory method then. Overloading based on the generic parameter of a method is just going to confuse the crap out of people, especially if they think the type is covariant on its parameter.

1337JiveTurkey
Feb 17, 2005

rjmccall posted:

I mean, Java's generics support is already too sophisticated by some metrics — most programmers don't understand the mathematics and just work around (misuses of) the type system with casts. And there's a lot more yet that Java generics can't express, like the co-/contra-variance of List<T> with T.

If Java could express covariance and contravariance of type parameters rather than making every method take some List<? extends T> instead, that'd fix my biggest complaint with its type system.

Reified types are a nice to have feature, but I think it comes up once every few months for me, and I write a lot of generic code. When it does come up, it's often some variation where the parent class is Bar<BP extends BaseParameter> and class Foo implements Bar<RefinedParameter> or class Foo<RP extends RefinedParameter> implements Bar<RP>. In that case it is possible to recover the type through Foo.class.getGenericInterfaces(). It's even more verbose than usual for Java (and that's saying something) but it's technically possible.

You need to find the Type which myType.equals(Bar.class), cast it (unsafely :v:) to a ParameterizedType and then getActualTypeArguments() to recover the parameter. In this case it would be the Class of RefinedParameter or WildcardType equivalent to ? extends RefinedParameter.

In practice, I've found just putting in a method Class<BP> Bar.getParameterType() which Foo implements to return RefinedParameter.class is often sufficient, if inelegant.

1337JiveTurkey
Feb 17, 2005

ToxicFrog posted:

:stonk:

Never programming in Java again was the best decision I ever made.

Closures over non-final variables can lead to some interesting situations:
code:
public Runnable stackSchmack() {
	int i = 1;
	return new Runnable() {
		public void run() {
			System.out.println(i++);
		}
	};
}

public static void main(String… argv) {
	Runnable r = stackSchmack();
	for (int i = 0; i < 100; i++) {
		new Thread(r).start();
	}
}

1337JiveTurkey
Feb 17, 2005

ToxicFrog posted:

I don't see how this is a "closures over non-final variables" issue as opposed to a "modifying shared state from multiple threads without synchronization" issue.

There's nothing to synchronize on because there's no reason you ever need to synchronize a local variable when only its thread can touch it. It's also a "the stack frame doesn't exist any more" issue and a "allowing pointers to reference the stack" issue. They're not insurmountable issues, but they add complexity to the language and reduce the scope of optimizations. Additionally, closures being by value means they behave consistently with method call semantics: No variable will be changed in a method unless it happens within the method itself. Java in this case chose consistency over "more checkboxes = better than" language design.

1337JiveTurkey
Feb 17, 2005

Beef posted:

What? You're spawning 100 instances of that same thread. Yes it is a concurrency issue.

Only because it's mutable. It's a violation of underlying language invariants for the sake of not using a Callable instead of a Runnable. That's what gets us languages like PHP.

1337JiveTurkey
Feb 17, 2005

Dessert Rose posted:

What underlying language invariants does this violate? You started 100 threads that all call a method on an object that mutates shared state without synchronization.

If you didn't want to have that shared state then don't close over it. Or assign it to a closure-local variable.

Changes to local variables are thread-safe and don't require synchronization. Activation records exist only within the context of a single thread. Activation record lifespans are coterminous with the execution of their associated method. You know, stuff that programmers generally take for granted to the point they don't even think about it any more.

quote:

C# handles this just fine.

What's the scope of a loop variable? Closures over variables introduce a lot of subtle issues as to how a language works which closures over values don't.

1337JiveTurkey
Feb 17, 2005

Jabor posted:

Sometimes closing over a value is the desired behaviour, but other times you want to close over a variable.

The syntax to close over a value when your closures close over variables is simple and isolated to the point that you create the closure - while the syntax to close over a variable when your closures only close over values is ugly and affects everywhere that variable is used.

And yet other times you want partial evaluation with pass-by-reference semantics. If there's perfectly serviceable language constructs for doing something like sharing mutable state throughout a program, we don't need to shoehorn that capability into constructs never intended for that purpose.

1337JiveTurkey
Feb 17, 2005

At a sufficient level of abstraction, everything is basically the same thing.

1337JiveTurkey
Feb 17, 2005

Getting started writing ReSTful Web Services with the ZWVP* platform. :suicide:

*z/OS, WebSphere AS, VSAM+CICS, PHP

1337JiveTurkey
Feb 17, 2005

Zombywuf posted:

What you're saying here is that ; is a synonym for ret ();. This has a pleasing symmetry but has no place in a language.

The semicolon's not a synonym; it's the empty statement afterwards that's a synonym for ret (). The semicolon's just acting as a Pascal-style statement separator rather than a C-style statement terminator. For a language which doesn't require semicolons as terminators, it's a lot more sensible to treat them as separators when they are used.

1337JiveTurkey
Feb 17, 2005

Jabor posted:

Threaded code? Pffft. Should be writing a jiter to get some actual performance or something, I mean I don't see any timing data or anything to indicate he's going the cycle-accurate route.

I think I remember someone that did an emulator which just translated the instructions to JVM opcodes but it seems like it'd be a bitch to actually split everything into procedures when developers historically could and did just screw with the stack.

1337JiveTurkey
Feb 17, 2005

Suspicious Dish posted:

I doubt that ever could have worked. JVM performs validation on every branch to make sure that local types and stack lengths/types match up as well. You would have to out-clever the original developers by padding stacks and knowing when to pop.

For very early systems I doubt that even if someone did get something working it'd be faster than interpretation due to all the edge cases that have to be tackled. Less limited systems seem more amenable because there's less pressure to take extreme measures for performance and some particularly troublesome options become impossible. For example self-modifying code in an architecture with a split cache and jumping into the middle of an instruction with a RISC instruction set.

I did find a project called JPSX which according to reports demonstrated full speed emulation of the Playstation using byte code translation with software graphics rendering to boot. There's a Google Code page for it with absolutely nothing though.

1337JiveTurkey
Feb 17, 2005

PrBacterio posted:

EDIT: vvv but there's no division happening here at run-time anywhere? it's all compile-time which even a straightforward and simple compiler should be able to optimize away during compile-time constant folding vvv

There wouldn't be half as much crappy code floating around if people recognized when their 'optimizations' were absolutely pointless.

1337JiveTurkey
Feb 17, 2005

There's lots of ways people get random numbers wrong and many of them aren't related to the algorithm used by the PRNG. It's still possible to get skewed probabilities even with a generator like Mersenne Twister. For example if a PRNG or even a genuine entropy source produced an output from 0-16, if you restricted the output modulo 15, the number 0 would be twice as likely to show up as all the other numbers.

1337JiveTurkey
Feb 17, 2005

Jabor posted:

Writing simulation software?

I mean there's a definite use-case for a repeatable PRNG, it's just not the most common case that people use random numbers for.

If you need a repeatable PRNG, the code actually needed to implement one of your own is about as simple to make cross-platform as humanly possible.

1337JiveTurkey
Feb 17, 2005

Burn everything down and replace it with Kerberos.

1337JiveTurkey
Feb 17, 2005

Honestly you'd probably get more mileage out of a "Code that you know in practice is terrible but still makes you go :smuggo:" thread.

1337JiveTurkey
Feb 17, 2005

Just have the affected people update their passwords and use the new work factor. Or just ask what circumstances a low work factor on some passwords would cause actual security issues that aren't totally overshadowed by all the other bad things that would need to happen first.

1337JiveTurkey
Feb 17, 2005

Hammerite posted:

The time articles linked by Aleksei have much the same issue. I would be interested in reading about why it is a misconception, as it is presented in part 2, that every year has either 365 or 366 days, but no explanatory link is provided.

The switch from julian to gregorian.

code:
$ cal 9 1752
   September 1752
Su Mo Tu We Th Fr Sa
       1  2 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

1337JiveTurkey
Feb 17, 2005

Using λ instead of halfLife or some other semantically meaningful variable name makes about as much sense as saying foo ࢠ Z/256Z rather than unsigned byte foo.

1337JiveTurkey
Feb 17, 2005

Doctor w-rw-rw- posted:

The horror is violated expectations, not the memory usage itself. It just feels inconsistent for Java to be a bloated memory-wasting machine except for numbers under 128, and inconsistent for a special class of non-objects. I would rather the padded walls be complete and total. I suppose I'm a bit of a purist. And even if everything is an object and there's no such thing as a primitive, there's nothing stopping the VM from figuring out how to optimize an Integer into an int behind the scenes rather than having it happen by hand.

If you're using Integers in a manner which would typically require the creation of a new object (hashcodes, reference equality, polymorphism, null values) and depending on primitive performance not in any contract, I'm not sure what you're looking for. What are they supposed to say? "Sure there's an obvious optimization which is such low hanging fruit that it's hovering at the very threshold of the gates of Hell, but we're going to leave it to you to decide whether it's worth it."

The problem is more the behavior than it is the performance. Any situation where a boxed primitive can plausibly be stored directly in a stack frame, Java 1.7 and above will do that instead. Having two options may have made sense in 1996, but now it's straightforward to optimize out those cases. The subtly different semantics are the real issue.

1337JiveTurkey
Feb 17, 2005

Doctor w-rw-rw- posted:

Are you arguing with me? Because I agree completely with exactly what you just said.

Calling Java's inability to offer performance guarantees on Integers a coding horror is a stretch of the term at best, especially in light of the capabilities of 15 year old embedded processors. It's a plausible decision for someone who doesn't know that client-side Java on internet toasters and JavaCards is a dream at best. It's still possible to be wrong by being way too conservative in retrospect without being a horror which is basically Java's longstanding problem. I reserve the term horror for languages like PHP where there often simply isn't a good reason at all and it's clear that it wasn't thought out and not Java where there's usually a reason but it might not have been the best one in light of experience.

Adbot
ADBOT LOVES YOU

1337JiveTurkey
Feb 17, 2005

In a modern IDE even if the method is some huge mess, syntax highlighting will tell you the scope so there's no need for any of that pFoo mBar fBuzz crap some ancient contractor left in the code that I'm trying to maintain right now. Getting the original declaration and associated comments are just a keystroke away and in a language with annotations it should display them as well. Annotations like @NotNull are far superior to some sort of naming convention that people may or may not follow.

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