Sunday, September 4, 2011

Polymorphism

If a class is newed in a struct method, then when the method finishes if the newed class memory is not deallocated, then we have a memory leak.

If a struct is defined in a class, then if assigned a different value in the class method, the value retains

struct allocated on the Stack
class allocated on the Heap

struct is just a block of memory.
class is a struct, except it is allocated on the heap, needs a constructor, and needs to be deallocated.

Why doesn't struct have a constructor? Does it?
Where did the concept of the constructor come from?
Where did the concept of the heap come from?

The concept of the heap probably came from OOP. OOP came from getting rid of if else statements. Can you work up the example?

How does executing one method based on type alleviate if-else statements and maintenance hell?

Maintenance hell is caused by trickling code changes. One small change demands many other places in the code to be changed too. What is an example of that?

Think macros, it's one layer of indirection. OOP is that too. This is in that Objective-C book.

The indirection happens at the method black box. The method remains intact, with exact typed inputs and outputs, the object type can be changed at runtime with polymorphism. So methods help, but how does objects factor into alleviating maintenance hell? Objects are sets of methods and properties, you can keep the original implementation plus add new ones (inheritance). With the old way you can't. You would have to rename the function where new functionality is required, which is a trickling change. So objects allow us to easily keep old implementation at the same time add new ones, using inheritance.

I'm sure in the beginning language designers just added methods and properties to structs, that essentially creates encapsulation, however that wasn't enough. What does encapsulation offer by itself without inheritance and polymorphism? Modularization. It clearly separates one module from another, but if you had similar structs, you wouldn't be able to reuse the similar parts, you would have to copy and paste them.

Inheritance and encapsulation both indicate language constructs, what you're doing when you are writing code. Polymorphism indicates behavior, runtime behavior.

So questions remain:
  1. Where exactly is the indirection?
  2. Why is constructor needed?
  3. How does heap help realize polymorphism?


Answers:
  1. The indirection happens at runtime. The same code gets redirected to the proper class based on type,determined at runtime, using vtables. Since the same code doesn't change, we've achieved indirection.
  2. Construction is needed because of encapsulation. It's the only chance for assigning external values to private properties. Encapsulation is needed because of modularization. Modularization is needed because of code reuse. Code reuse is achieved by polymorphism.
  3. Heap and polymorphism is unrelated. Heap = dynamic memory allocation, C has that (malloc).
    • Polymorphism is realized with vtables in C++.
    • A stack allocated object can't be persisted longer than the scope of the function.
    • A heap object can be used by many different methods.
    • In C++ structs can be inherited.


Conclusion:

Since polymorphism is about propagating code change without changing code, having heap objects polymorph rather than stack objects makes sense because they last longer throughout the code. Plus, syntactically there is no "newing" a stack object, so there is no place to declare the morphed (child) type. In a function, variables initiations are all localized in that scope, there is no chance to for the variable to morph unpredictably.

Saturday, November 27, 2010

SDL XCode OpenGL Project Template (Whales and Fish swimming)

Steps to get it to work in Windows XP Visual Studio 2010

Dynamically Linked
  • Install Nate Robin's GLUT for Win32.
  • Install SDL libs.
  • Setup the lib and include folders
          Project properties -> Configuration properties (CP) -> VC++ Directories -> Include Directories, Library Directories
  • CP -> Linker -> Input -> Additional Dependencies
          glut32.lib
          SDLmain.lib
          SDL.lib
  • Function mtime giving us shit. Spent time finding a replacement with CTime.h and the SDL Timer, that was stupid. Since mtime is not used, just scratch it and return 0.
  • Comment out glutSwapBuffers() in Atlantis_Display(void). The display works without it, might be an issue with glEnd() not being called afterwards. Didn't look into it deeper, don't need to, it works.
  • Copy SDL.dll and glut32.dll to the same folder as the executable.

Statically Linked (Single Executable)
  • Download GLUT and SDL source, compile them into static libs.
          CP -> General -> Configuration Type -> Static Library (.lib)
  • Disable the post build events for GLUT
          CP -> Build Events -> Post-Build Event -> Use In Build -> No
  • Fuck with the Runtime Library settings
          CP -> Code Generation -> Runtime Library -> /MD (for all 3 projects)
          CP -> General -> Use of MFC (Don't think this matters too much, but here's the config currently)
          This Project = Use Standard Windows Libraries
          GLUT = Use Standard Windows Libraries
          SDL = Use MFC in a Shared DLL
  • Turn on verbose
          CP -> Linker -> General -> Show Progress -> /Verbose
  • Realize from the output that searching in glut32.lib is not finding glutBitmapCharacter()
  • Added a all of the directX libs because thought SDL needed it, verbose also let us know we only need dxguid.lib
  • Try a whole bunch of shit, read a whole bunch of pages to resolve the glutBitmapCharacter() issue.
  • Cannot have __declspec(dllimport) on static lib functions, so just delete GLUTAPI at the front, making it
          void APIENTRY glutBitmapCharacter(void *font, int character);
  • You don't even need the extern keywords because it's all statically linked.
  • Change for both the header file in source and the include one, recompile GLUT, overwrite old lib, recompile project.

Conclusion

      Don't use GLUT, stick to SDL bitch.

Dynamic
Static
Static libs
SDL
GLUT

Thursday, September 23, 2010

Boundary Conditions

Inspired by http://msdn.microsoft.com/en-us/library/cx9s2sy4.aspx

19 - 3 = 16

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
1 2 3 4 5 6 7  8  9 10 11 12 13 14 15 16 17

But when the numbers are listed out, there are 17 items, not 16. Why?

Take the simplest example:

2 - 1 = 1
1 2

1 - 0 = 1
0 1

Both of these have at least 2 elements in the cardinality.
This may have something to do with the number of operands (Arity).

So take an example with arity 3 (Ternary):

19 - 3 - 5 = 11

[19 - 3]
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
1 2 3 4 5 6 7  8  9 10 11 12 13 14 15 16 17

[19 - 3 - 5]
8 9 10 11 12 13 14 15 16 17 18 19
1 2  3  4  5  6  7  8  9 10 11 12

It has nothing to do with arity.

It's counting the gaps between the numbers.

3 4 5 6 7 8 9 10 11 12 13  14  15  16  17  18  19
 1 2 3 4 5 6 7  8  9  10 11  12  13  14  15  16

If numbers represent physical things/items, then why does the subtraction operation count gaps?

1 2 3
3 - 2 = 1

1 2 3 4
4 - 2 = 2

c - b = a
minuend (c) - subtrahend (b) = difference (a)

In the second example, counting from the left starting at 1 going towards the right are the numbers included in the subtrahend, and the numbers from the minuend to the subtrahend (difference) goes from right to left (starting at 4 ending at 2). Both of these beasts want to gobble up 2. If the focus is set on the numbers in the subtrahend then 2 is gobbled up by it (1 2). If the focus is set on the numbers in the difference then 2 is gobbled up by IT (2 3 4). Logically speaking, 2 should be included in the subtrahend only because it is one of the numbers to be taken away by the subtraction, but the difference wants to gobble up the 2 because the 2 is a focal point of interest in the equation we are trying to speak and to get the difference is the goal of our speech. So logically the difference should only include (3 4) without the 2.

How does all this relate to the MSDN article? The for-loop runs from i = 3 to 19, which is 17 times, but 19 - 3 = 16. This is a situation where the subtraction operation yields the wrong result because the logical focus is actually on the difference rather than the subtrahend. So the 3 is taken by the for-loop in the code to run its contents, leaving the normal conventions of a subtraction operation blind & behind in the dust. This gap between math and code needs to be explored further. My gut feeling is that different levels of abstraction will rotate in and out of phase with code in sort of a yin yang duality kind of way. We'll see what happens, but for now, the train rolls on...