Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 13 14 [15] 16 17 ... 795

Author Topic: if self.isCoder(): post() #Programming Thread  (Read 804518 times)

Max White

  • Bay Watcher
  • Still not hollowed!
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #210 on: January 08, 2012, 08:32:58 pm »

It's basically a Lisp variant on the JVM, so you can access any Java library you need with a few lines of magic glue

He is talking about clojure.

Stargrasper

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #211 on: January 08, 2012, 08:36:35 pm »

It's basically a Lisp variant on the JVM, so you can access any Java library you need with a few lines of magic glue

He is talking about clojure.

I figured as much.  I just don't feel like having to take the moment to guess.
Logged

Stargrasper

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #212 on: January 08, 2012, 10:58:30 pm »

Who wants to know how royally pissed Stargrasper is right now?  Hint:
Code: [Select]
stargrasper.anger = new BigInteger(Long.MAX_VALUE + "").multiply(new BigInteger(Long.MAX_VALUE + ""));

I was looking into why whoever's code that was with the Scanner that wasn't working right.  Apparently I'm wrong.  And the university professor that taught me to program.  And my textbooks.  And half the internet.  Remember when I said to you all to prove == doesn't work for String with a counterexample?  I found three.

The first is that Scanner example.

The second is input from a JOptionPane as follows:
Code: [Select]
String s = JOptionPane.showInputDialog("");
System.out.println(s == "foo");

The third is explicit creation of strings.
Code: [Select]
String s1 = new String("foo");
String s2 = new String("foo");
System.out.println(s1 == s2);

So why is it working in every other example I've ever seen ever!?  I'll tell you why!  Java if royally f*ed up with how it instantiates Strings!
Code: [Select]
String s1 = new String("foo");
String s2 = new String("foo");
System.out.println("==: " + s1 == s2);
System.out.println("equals: " + s1.equals(s2));
System.out.println("hashCode: " + (s1.hashCode() == s2.hashCode()));
System.out.println("\t" + s1.hashCode());
System.out.println("\t" + s2.hashCode());
System.out.println("compareTo: " + s1.compareTo(s2));
String s1id = Integer.toHexString(System.identityHashCode(s1));
String s2id = Integer.toHexString(System.identityHashCode(s2));
System.out.println("idHash: " + s1id.equals(s2id));
System.out.println("\t" + s1id);
System.out.println("\t" + s2id);
Guess what this outputs?
Code: [Select]
==: false
equals: true
hashCode: true
101574
101574
compareTo: 0
idHash: false
ecf2c09
43540a77
== returns FALSE, meaning they aren't the same.
equals returns TRUE, meaning they're the same.
hashCode returns SAME, meaning they're the same.
compareTo returns 0, meaning they're the same.
identityHashCode returns DIFFERENT, meaning they aren't the same.

Why is hashCode returning the same!?  I can understand equals doing it.  I can even understand compareTo doing it.  Why would hashCode be overridden in such a way as to return the same if they aren't the same!?

The real damning thing here is the System.identityHashCode(object).  There is simply no possible way to get the actual memory location of an object from Java or the JVM.  It just can't be done.  In fact, Java and the JVM move data around in memory.  I know it's trying to be efficient, but still!  The identityHashCode is how the system identifies that object.  Notice how they're different?  That implies that == really is comparing either the memory location or the identityHashCodes of the two objects.  But then why does it work for normal circumstances?  You're going to love this!
Code: [Select]
String s1 = "foo";
String s2 = "foo";
System.out.println("==: " + s1 == s2);
System.out.println("equals: " + s1.equals(s2));
System.out.println("hashCode: " + (s1.hashCode() == s2.hashCode()));
System.out.println("\t" + s1.hashCode());
System.out.println("\t" + s2.hashCode());
System.out.println("compareTo: " + s1.compareTo(s2));
String s1id = Integer.toHexString(System.identityHashCode(s1));
String s2id = Integer.toHexString(System.identityHashCode(s2));
System.out.println("idHash: " + s1id.equals(s2id));
System.out.println("\t" + s1id);
System.out.println("\t" + s2id);
outputs
Code: [Select]
==: true
equals: true
hashCode: true
101574
101574
compareTo: 0
idHash: true
ecf2c09
ecf2c09
Look at the identityHashCodes of those two strings.  They're the same.  They're initialized independently.  When I just type things in quotations, it's supposed to instantiate a new String object there.  Java is considering them both to be the same thing in memory, probably because they have the same "name"!

It gets better!  They're the same thing in memory, but if you change one, it reallocates memory for it, finally instantiating it as a new String while leaving the other where it was.
Code: [Select]
String s1 = "foo";
String s2 = "foo";
System.out.println(s1);
System.out.println(s2);
System.out.println("==: " + (s1 == s2));
System.out.println("equals: " + s1.equals(s2));
System.out.println("hashCode: " + (s1.hashCode() == s2.hashCode()));
System.out.println("\t" + s1.hashCode());
System.out.println("\t" + s2.hashCode());
System.out.println("compareTo: " + s1.compareTo(s2));
String s1id = Integer.toHexString(System.identityHashCode(s1));
String s2id = Integer.toHexString(System.identityHashCode(s2));
System.out.println("idHash: " + s1id.equals(s2id));
System.out.println("\t" + s1id);
System.out.println("\t" + s2id);

System.out.println("");

s2 += "bar";
System.out.println(s1);
System.out.println(s2);
System.out.println("==: " + (s1 == s2));
System.out.println("equals: " + s1.equals(s2));
System.out.println("hashCode: " + (s1.hashCode() == s2.hashCode()));
System.out.println("\t" + s1.hashCode());
System.out.println("\t" + s2.hashCode());
System.out.println("compareTo: " + s1.compareTo(s2));
s1id = Integer.toHexString(System.identityHashCode(s1));
s2id = Integer.toHexString(System.identityHashCode(s2));
System.out.println("idHash: " + s1id.equals(s2id));
System.out.println("\t" + s1id);
System.out.println("\t" + s2id);
outputs
Code: [Select]
foo
foo
==: true
equals: true
hashCode: true
101574
101574
compareTo: 0
idHash: true
43540a77
43540a77

foo
foobar
==: false
equals: false
hashCode: false
101574
-1268878963
compareTo: -3
idHash: false
43540a77
427b2d29
What is Java doing!?  Its messing with its own internal pointers (that we don't have access to) in such a way as to attempt to be efficient.

It turns out in almost all circumstances, that is, all of those cases we showed worked, so many that even my professor was fooled into thinking it worked, Java is pulling this stunt where it points several different instantiations to the exact same place in memory!

The question is no longer "what is == actually doing?".  We, or I anyway, know what it's doing now.  Now the question is "how is Java implicitly instantiating Strings?"  I will keep looking into this.  I now very deeply want to understand what's happening.
Logged

Max White

  • Bay Watcher
  • Still not hollowed!
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #213 on: January 08, 2012, 11:14:21 pm »

import JRage.*;

In other news...

Spoiler (click to show/hide)
A lone ascii character stands, looking over a poorly genned ocean. He is excited at the deep and wonderful colors that surround him, knowing more and more will fill the world he occupies, but something is also troubling him.
For now, the world is a safe place, but that will all change, ever so quickly, and suddenly every tick will become a challenge to survive.

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #214 on: January 08, 2012, 11:24:03 pm »

I had a suspicion that I kept to myself, but now you've provided evidence that it may be correct. It's similar to an issue that C++ has, but slightly different.

Code: [Select]
String s = "foo";
I think Java is first creating an anonymous constant (read: final) String for "foo", and then copy-constructs s from it. So, when you initialize two Strings this way, they are both referencing that anonymous constant.

Code: [Select]
String s = new String("foo");
Here, s is being constructed properly, so it has its own place in memory, rather than being a reference to "foo".

I'm not entirely sure how hashCode and idHash work, but I'd imagine hashCode creates a hash based on the contents of the String, while idHash creates a hash based on the location in memory. If that's true, then my interpretation seems to follow the results of your tests.

In C++, a similar problem occurs when you try to use string literals like "foo". To provide backwards compatibility with C, string literals are actually of type const char* (or const char[], but that's a different story), meaning that they're arrays of constant characters. That means you can't do stuff like use string::at on them, because they have no member methods. The reason I say this problem is similar is because, to construct a string in C++, you actually construct a character array first, and then construct a string object from that.



New rule for this thread: You can bash Java all you want, as long as you provide an original reason for bashing it. Including a positive quality is optional and not recommended.

Max White

  • Bay Watcher
  • Still not hollowed!
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #215 on: January 08, 2012, 11:27:31 pm »

New rule for this thread: You can bash Java all you want
:D

as long as you provide an original reason for bashing it.
::)
I have things do to! A roguelike to program! You can't expect me to fuck around with the ins and outs of this newer Java to validate my bashing of it!

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #216 on: January 08, 2012, 11:41:38 pm »

Found some new stuff at http://docs.oracle.com/javase/6/docs/api/ to fuel the hatred.

Quote from: System.identifyHashCode
public static int identityHashCode(Object x)

    Returns the same hash code for the given object as would be returned by the default method hashCode(), whether or not the given object's class overrides hashCode(). The hash code for the null reference is zero.

Quote from: Object.hashCode()
public int hashCode()

    Returns a hash code value for the object. This method is supported for the benefit of hashtables such as those provided by java.util.Hashtable.

    The general contract of hashCode is:

        Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
        If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
        It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.

    As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)

The String class is indeed overloading Object.hashCode(). The next step is to cast two identical Strings back to Objects and compare their hashCode values.

This is very frightening:

Code: [Select]
public class Strings {
    public static void main(String args[]) {
        String s1 = new String("foo");
        String s2 = new String("foo");
        System.out.println("==: " + s1 == s2);
        System.out.println("equals: " + s1.equals(s2));
        System.out.println("hashCode: " + (s1.hashCode() == s2.hashCode()));
        System.out.println("\t" + s1.hashCode());
        System.out.println("\t" + s2.hashCode());
        System.out.println("compareTo: " + s1.compareTo(s2));
        String s1id = Integer.toHexString(System.identityHashCode(s1));
        String s2id = Integer.toHexString(System.identityHashCode(s2));
        System.out.println("idHash: " + s1id.equals(s2id));
        System.out.println("\t" + s1id);
        System.out.println("\t" + s2id);
       
        System.out.println();
       
        Object o1 = (Object)s1;
        Object o2 = (Object)s2;
       
        System.out.println("hashCode: " + (o1.hashCode() == o2.hashCode()));
        System.out.println("\t" + o1.hashCode());
        System.out.println("\t" + o2.hashCode());
    }
}

Code: (Output) [Select]
false
equals: true
hashCode: true
101574
101574
compareTo: 0
idHash: false
100ebec
180f96c

hashCode: true
101574
101574

The rule on Java has been changed. It will be exiled from this thread. It is now known as the Language Which Shall Not Be Named (Or Used).

Stroustrup help us all.

Levi

  • Bay Watcher
  • Is a fish.
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #217 on: January 08, 2012, 11:43:49 pm »

That makes sense though, doesn't it?  The hashcode is more for lookups in hashmaps and things, its not supposed to be used as a unique ID sort of deal.



Edit:  I dislike java too, but I think that small bit of it makes a sort of sense.
« Last Edit: January 08, 2012, 11:48:22 pm by Levi »
Logged
Avid Gamer | Goldfish Enthusiast | Canadian | Professional Layabout

Max White

  • Bay Watcher
  • Still not hollowed!
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #218 on: January 08, 2012, 11:44:53 pm »

The rule on Java has been changed. It will be exiled from this thread. It is now known as the Language Which Shall Not Be Named (Or Used).
Whoa, let's not take things too far.
It does what it does and it does it well. It is like New Zealand, I will pay it out, but in truth it ain't so bad, it is just a sporting thing. I don't follow sport, so I follow programming languages instead.

I got prolog to win this year! Gotta be it's year dammit!

Stargrasper

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #219 on: January 08, 2012, 11:50:12 pm »

New rule for this thread: You can bash Java all you want, as long as you provide an original reason for bashing it. Including a positive quality is optional and not recommended.
No fair!  I have to write tutorials for it, encourage people to use it, bash it, AND deal with everyone else bashing it!?

Also, System.identityHashCode(object) has nothing to do with the memory address.  It's just a constant identifier for any given object.  This can be said because Java will actually move the data for an object around in memory without changing the identityHashCode.  I'm still not sure how Java implicitly instantiates these things.  That's my next project to figure out.  My guess is that I'm constructing something that it realizes more or less exists and just notates somewhere that they aren't actually the same so that when I change one, it reallocates memory for it.  Or it reallocates memory every time I change something...i didn't actually check that.  *checks*
Code: [Select]
String s = "foo";
System.out.println(Integer.toHexString(System.identityHashCode(s)));
s += "bar";
System.out.println(Integer.toHexString(System.identityHashCode(s)));
output
Code: [Select]
1ae73783
41ed8741

Please tell me all it did was change the id and not actually reallocated memory just because I changed it...it is a hash function, it should change...but did it reallocate memory, too?

The better way to test your theory would be to implicitly construct a String, wait for any hidden instantiation to get garbage collected and then implicitly instantiate another one...wait, I know how to force the garbage collector to run...
Code: [Select]
String s1 = "foo";
System.out.println(Integer.toHexString(System.identityHashCode(s1)));
System.gc();
String s2 = "foo";
System.out.println(Integer.toHexString(System.identityHashCode(s2)));
Nope.
Code: [Select]
41ed8741
41ed8741

If it were constructing an anonymous constant or something, I'd imagine it would go away when the garbage collector is run.  In fact, it's unthinkable that something no longer being used wouldn't die when the garbage collector runs.  Otherwise it would have to spend the time to check all existing objects in memory for a match.  I would think that would be ridiculously inefficient.  Java isn't exactly known for being efficient, though.

The rule on Java has been changed. It will be exiled from this thread. It is now known as the Language Which Shall Not Be Named (Or Used).

Stroustrup help us all.

Does that mean I'm not allowed to keep writing Java tutorials?

Also, if you cast two Strings to Objects and call hashCode()...it doesn't call Object's hashCode().  Java is smart enough to realize it's a String and will call the String hashCode() method even though it's casted as an Object.  That argument, at least, is not valid.

The rule on Java has been changed. It will be exiled from this thread. It is now known as the Language Which Shall Not Be Named (Or Used).
Whoa, let's not take things too far.
It does what it does and it does it well. It is like New Zealand, I will pay it out, but in truth it ain't so bad, it is just a sporting thing. I don't follow sport, so I follow programming languages instead.

I got prolog to win this year! Gotta be it's year dammit!

Yeah, don't go overboard.  I put a lot of work into those tutorials you're trying to exile!

Prolog...<shutter>
Logged

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #220 on: January 08, 2012, 11:52:12 pm »

Except that it is, when you use System.identifyHashCode or the hashCode method of any object except a String object. The String hashCode method is overloaded to return a hash based on the contents of the String, rather than the memory location (unlike EVERY OTHER CLASS). When you cast it back to an Object, the hashCode method still returns the same as the String object would. However, System.identifyHashCode(Object x), which is supposed to return x.hashCode(), returns differently than String.hashCode.

Also, String objects constructed with new are considered different according to the == operator, while String objects constructed like primitives with the same literal are considered identical.

Spoiler (click to show/hide)

EDIT: This is in response to Levi's post.

EDIT 2: C++ will be the winner, as always.
« Last Edit: January 08, 2012, 11:59:49 pm by Mego »
Logged

Levi

  • Bay Watcher
  • Is a fish.
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #221 on: January 09, 2012, 12:02:02 am »

I admit I'm not very familiar with Java.  I'm actually a little surprised it has casting at all, it didn't seem like the kind of language which would allow that.

Out of curiosity, after you cast the string into an object, what do you get when you try to print o1.getClass().getName()?
« Last Edit: January 09, 2012, 12:04:46 am by Levi »
Logged
Avid Gamer | Goldfish Enthusiast | Canadian | Professional Layabout

Stargrasper

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #222 on: January 09, 2012, 12:17:51 am »

I admit I'm not very familiar with Java.  I'm actually a little surprised it has casting at all, it didn't seem like the kind of language which would allow that.

Out of curiosity, after you cast the string into an object, what do you get when you try to print o1.getClass().getName()?

java.lang.String
Code: [Select]
String s = "foo";
Object o = (Object) s;
System.out.println(o.getClass().getName());

Rule of thumb, regardless of what it's casted as, Java is smart enough to usually realize what it really is (and call appropriate methods).  And how exactly would you imagine an object oriented language not having casting?
Logged

Max White

  • Bay Watcher
  • Still not hollowed!
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #223 on: January 09, 2012, 12:19:21 am »

Also, String objects constructed with new are considered different according to the == operator, while String objects constructed like primitives with the same literal are considered identical.

Hmm, make sure you are dealing with 'Strings' and not 'strings'.
Chances are that Java is trying to be a little more c#, thus making strings act more like a primitive, but instead of adding functionality to a class, it now has a new thing called a 'string', and that can be used as a String, but acts differently.
So polymorphism is fucking you up.

I would look for this in the docs myself, but too busy making the grass turn red when you spill blood onto it.

Heron TSG

  • Bay Watcher
  • The Seal Goddess
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #224 on: January 09, 2012, 12:20:25 am »

Does anyone know if Codecademy is any good for learning JavaScript? I am attempting to use that in combination with HTML 5 to develop a game.
Logged

Est Sularus Oth Mithas
The Artist Formerly Known as Barbarossa TSG
Pages: 1 ... 13 14 [15] 16 17 ... 795