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
Spatial
Nov 15, 2007

Java code:
public class Stack<E> {

	E[] elements;
	int maxSize;
	int top;


	
	public int push(E elem) {
		if (top == maxSize)
			throw new RuntimeException();

		elements[++top] = elem;

		return 1;
	}



	public int pop(E elem) {
		if (top == 0)
			throw new RuntimeException();

		elem = elements[top--];

		return 1;
	}
	
	

	public Stack( int size ) {
		top      = -1;
		maxSize  = size;
		elements = (E[]) new Object[ size ];
}
Written by my data structures lecturer.

Adbot
ADBOT LOVES YOU

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
What's wrong with it, other than having it be a bounded size?

EDIT: whoops, didn't read pop() enough carefully. It seems this is a C guy who was forced into Java.

kitten smoothie
Dec 29, 2001

My first thought: "What's wrong with an array implementation? It's even in the CLR book."
My second thought: "Oh."

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?
It seems like if you push one thing and then try to pop it you'll get an exception?

Edit: Also, returning 1. I'm guessing that was originally error handling but now it's just pointless

carry on then
Jul 10, 2010

by VideoGames

(and can't post for 10 years!)

Let me guess, they also think Java is pass-by-reference for objects.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
If you instantiate, push, pop, you get an exception because he starts at -1 instead of 0.

You must push a sacrificial element to this implementation. I would recommend pushing it's own reference.

E;f,b...

Sedro
Dec 31, 2008

HappyHippo posted:

It seems like if you push one thing and then try to pop it you'll get an exception?

Volmarias posted:

If you instantiate, push, pop, you get an exception because he starts at -1 instead of 0.

You must push a sacrificial element to this implementation. I would recommend pushing it's own reference.

E;f,b...
No, it works
Java code:
top = -1;
elements[++top] = elem; // top = 0, elements[0] = elem
elem = elements[top--]; // elem = elements[0], top = -1
Edit: oh, nevermind
Java code:
if (top == 0)
    throw new RuntimeException();

Freakus
Oct 21, 2000
Also, memory leak: references to popped elements stay around until that spot is re-used.

Zombywuf
Mar 29, 2008

Xerophyte posted:

Note: consider not trying to learn Agda.

I've almost managed to write a modulus function on nats that passes the termination checker.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Freakus posted:

Also, memory leak: references to popped elements stay around until that spot is re-used.

Aha, good catch. Obviously not a leak in C but he doesn't know Java at all.

PrBacterio
Jul 19, 2000
Also nobody has commented on the fact that, why the hell do the push and pop functions return an int? And why do they always return the value 1?

vvv I knew that, it's a rhetorical question to bring attention to the fact that this, too, is a horror vvv

PrBacterio fucked around with this message at 04:35 on Mar 10, 2013

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Because it originally looked like this:

C++ code:
int stack_push (Stack *stack, void *elem);
int stack_pop (Stack *stack, void *elem_out);

ninjeff
Jan 19, 2004

Spatial posted:

Java code:
(E[]) new Object[ size ]

Arrays don'tshouldn't work that way!

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.
It's Java, that's how they do work. Yay type erasure. Though JDK code casts elements, not arrays, from what I remember.

ninjeff
Jan 19, 2004

Aleksei Vasiliev posted:

It's Java, that's how they do work. Yay type erasure. Though JDK code casts elements, not arrays, from what I remember.
It's array covariance, not type erasure - C# and VB have the same problem despite having real generics :eng99:

Flobbster
Feb 17, 2005

"Cadet Kirk, after the way you cheated on the Kobayashi Maru test I oughta punch you in tha face!"

ninjeff posted:

Arrays don'tshouldn't work that way!

Every semester when I teach my data structures course, I spend a good 10 minutes ranting about Java's horrible design decisions when it comes to generics, especially about how there's no legitimate reason to NOT allow new E[...] since E is always going to be an object type so the compiler should just allocate an Object array and implicitly do the cast for me.

And then the cast isn't even enough, I have to @SuppressWarnings to completely shut it up. :suicide:

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

PrBacterio posted:

vvv I knew that, it's a rhetorical question to bring attention to the fact that this, too, is a horror vvv

I guess I don't understand what's wrong with it in C.

PrBacterio
Jul 19, 2000

Suspicious Dish posted:

I guess I don't understand what's wrong with it in C.
There's nothing wrong with it in C and I never said it was, but that was written in Java and it served absolutely no purpose there? :confused:

ExcessBLarg!
Sep 1, 2001

Suspicious Dish posted:

Because it originally looked like this:

C++ code:
int stack_push (Stack *stack, void *elem);
int stack_pop (Stack *stack, void *elem_out);
This is an amusingly perfect description of what was obviously the original C (or C++ I guess) version. Because it's exactly as useless as the Java one.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Why?

ExcessBLarg!
Sep 1, 2001
There's no useful way to get the element out of "pop" (or "stack_pop") since the assignment is local to that method only. It actually makes the data structure completely useless since it's "input only".

In other words:

carry on then posted:

Let me guess, they also think Java is pass-by-reference for objects.

Zemyla
Aug 6, 2008

I'll take her off your hands. Pleasure doing business with you!

Shugojin posted:

The entirety of Numerical Recipes in C and how they didn't completely port it from Numerical Recipes in FORTRAN so every single loving bit of array math starts at 1 instead of 0 so you need to constantly shift so that it accesses what you want :suicide:
Oh god yes. I used it as a pedagogical text in high school, and then when I got to college I found out about the GNU Scientific Library. Seriously, screw 1-based arrays in C.

FAKE EDIT: Also, I'm pretty sure ptr - 1 isn't even valid Standard C, since it can have undefined behavior.

carry on then
Jul 10, 2010

by VideoGames

(and can't post for 10 years!)

ExcessBLarg! posted:

There's no useful way to get the element out of "pop" (or "stack_pop") since the assignment is local to that method only. It actually makes the data structure completely useless since it's "input only".

Yeah, but how is the C one just as useless?

ExcessBLarg!
Sep 1, 2001

Zemyla posted:

FAKE EDIT: Also, I'm pretty sure ptr - 1 isn't even valid Standard C, since it can have undefined behavior.
(ptr-1) is valid for any complete (not void *) pointer type.

ExcessBLarg!
Sep 1, 2001

carry on then posted:

Yeah, but how is the C one just as useless?
Although not obligated, presumably the implementation of the function is:
code:
...
elem_out = elem;
...
And just like in the Java version, the assignemnt to elem_out is meaningless since it doesn't influence any program state outside the "stack_pop" method.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

ExcessBLarg! posted:

There's no useful way to get the element out of "pop" (or "stack_pop") since the assignment is local to that method only. It actually makes the data structure completely useless since it's "input only".

Not in C. Perhaps I should have put void **elem_out as the signature instead, but it's the same.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

ExcessBLarg! posted:

Although not obligated, presumably the implementation of the function is:
code:
...
elem_out = elem;
...

That wouldn't make any sense. The implementation would be *elem_out = elem; which would assign to the out pointer.

ExcessBLarg!
Sep 1, 2001

Suspicious Dish posted:

Not in C. Perhaps I should have put void **elem_out as the signature instead, but it's the same.
That's exactly the point though. To make "stack_pop" useful in C, you have to pass a double-pointer and assign to the deferenced pointer. Java doesn't have "double-pointers" so there's no way to assign a method reference as they're passed by value.

Java object references aren't like C++ references. Actually they're more like implicit C/C++ pointers. All Java objects are dynamically allocated from the heap (but automatically freed by the garbage collector). The Java "." operator is equivalent to the C(/C++) "->" operator for struct(/class) types. However, there's no "*" or "&" operators, no double-pointers, no pass-by-reference, etc.

There's only two three ways to get an object reference "out" of a method in Java:
  • Return it.
  • (Edit:) Throw it as an exception, assuming a throwable object.
  • Assign it to a field in a different object that's passed into the method, possibly an entirely superfluous single-field container object used to emulate C/C++ double pointers.

Edit:

Suspicious Dish posted:

That wouldn't make any sense.
Agreed, however that's entirely equivalent to what the posted Java code actually does. Hence my original comment.

ExcessBLarg! fucked around with this message at 18:58 on Mar 10, 2013

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

ninjeff posted:

It's array covariance, not type erasure - C# and VB have the same problem despite having real generics :eng99:

Huh?

C# code:
public class Test<T>
{
    T[] SomeArray;
    public Test(int Size)
    {
        SomeArray = new T[Size];       
    }
}
Compiles fine.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
Yeah, I'm assuming that he took away things like * which caused compile errors in Java. So it was probably something like

code:
int stack_pop (Stack *stack, void **elem_out) 
{
  if(top == 0) {
    return 0;
  }
  *elem_out = elements[top--];
  return 1;
}
with the expected usage of

code:
void** element;
if(stack_pop(my_stack, element)) {
  // do something with element
} else {
  // oh no!
}
(My C is so rusty ogad I'm probably causing a segfault)

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

ExcessBLarg! posted:

That's exactly the point though. To make "stack_pop" useful in C, you have to pass a double-pointer and assign to the deferenced pointer. Java doesn't have "double-pointers" so there's no way to assign a method reference as they're passed by value.

Java object references aren't like C++ references.

Yes, we know. What we're saying is that this guy used to teach C or C++, and then got stuffed into a Java course, and naively fiddled around enough to make his lesson plans compile, but not actually work.

Amarkov
Jun 21, 2010

Suspicious Dish posted:

Yes, we know. What we're saying is that this guy used to teach C or C++, and then got stuffed into a Java course, and naively fiddled around enough to make his lesson plans compile, but not actually work.

If nothing else, this is the only explanation for using a RuntimeException to indicate an empty stack. "Hmm, I don't know what this 'throws' clause is, I'll just find a way to not have to use it."

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?
Not to mention the half implemented "using ints to indicated success or failure" idiom.

Shugojin
Sep 6, 2007

THE TAIL THAT BURNS TWICE AS BRIGHT...


Zemyla posted:

Oh god yes. I used it as a pedagogical text in high school, and then when I got to college I found out about the GNU Scientific Library. Seriously, screw 1-based arrays in C.

FAKE EDIT: Also, I'm pretty sure ptr - 1 isn't even valid Standard C, since it can have undefined behavior.

I was working on something that relied upon an unholy, uncommented union of NR's Levernberg-Marquardt fitting method and GSL libraries last week and bitching about NR in here was one of my rewards for success.

As a first encounter with GSL it was... Suboptimal.

All the GSL calls and such were fine but all the logic for calling it relied on NR's absolute horseshit.

Qwertycoatl
Dec 31, 2008

HappyHippo posted:

Huh?

C# code:
public class Test<T>
{
    T[] SomeArray;
    public Test(int Size)
    {
        SomeArray = new T[Size];       
    }
}
Compiles fine.

The problem C# has with array covariance is this:
C# code:
class Base
{
}
class Derived : Base
{
}

// This function should never throw an exception, right?
// Wrong. SetBase(new Derived[1]) compiles, and the array access throws
// ArrayTypeMismatchException
static void SetBase(Base[] arr)
{
   if (arr.Length > 0)
      arr[0] = new Base();
}

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

Qwertycoatl posted:

The problem C# has with array covariance is this:
C# code:
class Base
{
}
class Derived : Base
{
}

// This function should never throw an exception, right?
// Wrong. SetBase(new Derived[1]) compiles, and the array access throws
// ArrayTypeMismatchException
static void SetBase(Base[] arr)
{
   if (arr.Length > 0)
      arr[0] = new Base();
}

Right. But does that affect this case (with the stack class the prof is trying to make)?

C# code:
class Vehicle
{
}
class Car : Vehicle
{
}
class Spaceship : Vehicle
{
}

public class Test<T>
{
    T[] SomeArray;
    public Test(int Size)
    {
        SomeArray = new T[Size];       
    }

    public void AddSomeItem(T item, int index)
    {
        SomeArray[index] = item;
    }
}

...

Test<Vehicle> test = new Test<Vehicle>(10);
test.AddSomeItem(new Car(), 0);
test.AddSomeItem(new Spaceship(), 5);
Works fine. Am I missing something?

Qwertycoatl
Dec 31, 2008

HappyHippo posted:

Right. But does that affect this case (with the stack class the prof is trying to make)?

code:
...
Works fine. Am I missing something?

No, that's fine. C# isn't as crazy as Java, it's just a bit crazy.

ninjeff
Jan 19, 2004

Aleksei Vasiliev posted:

It's Java, that's how they do work. Yay type erasure. Though JDK code casts elements, not arrays, from what I remember.
I just read the replies above and thought about it some more, and you were right - I just assumed, coming from the .NET world, that this would be legal and that the author of the awful stack class just hadn't known about it:
Java code:
new E[size]
So it's a good thing that Java has the awful feature of array covariance to allow you to work around its awful feature of type erasure!

Bhaal
Jul 13, 2001
I ain't going down alone
Dr. Infant, MD
Don't forget the out of bounds indexing when you pop() an empty Stack, or the out of bounds indexing when you try to push size+1 elements in, and both cases the class cheerfully makes the attempt. Man, a data structures lecturer who completely bombs array index math 101, that's a new one.

Adbot
ADBOT LOVES YOU

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug
A co-worker stomped over a change I made to a source controlled file today.

The horror is that we're both ALM consultants and this guy's spent hundreds if not thousands of hours teaching people how to use source control.

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