Archive for programming

A Phenomenal Grasp of Grammar and a Superlative Command of Syntax

Sure, I’m only in my second year at George Mason for my Computer Science degree. But I’ve seen Java, I’ve seen Lua, I’ve seen C and Lisp and JavaScript (yes, that one is a programming language, too). At this time, I have decided to flout convention and talk about a syntax in general for an object oriented language. Call it Floop. Call it EEzle. I don’t care. It represents what I have come to like and dislike in basic syntax of a few programming languages, most of them scripting (Python, Lua, Ruby).

Arrays and Hashes

Arrays in Python are great. You slice them up so:

first=foo[0]
some_section=foo[2:5]
middle=foo[1:-1]
last=foo[-1]
last_three_items=foo[-3:]
everything_but_last_three_items=foo[:-3]

And so on. Ruby uses colons for symbols, so it can only attempt this with its slice() method. This is also why Python’s simple dictionary syntax is not viable for Ruby.

some_python_dict={"bat":2, "cat":3, "dog":7}

some_ruby_hash={"bat"=>2, "cat"=>3, "dog"=>7}

Either one of these seems reasonable. Equals with greater-than creates a sort of arrow.

Lua is cool in that all its arrays are also hashes, indexed with integers:

lua_list={2, 3, 7}

lua_table={bat=2, cat=3, dog=7}

I would have all arrays really be hashes like Lua’s tables. How hard is performance hit? For those who haven’t seen Lua code, list indexes start at one, not zero! I’m down with that, though it does take a little while to get used to.

Python tuples to me are pointless. We might as well use lists. How hard is performance hit using dynamic lists instead of tuples? For all situations, lists can indeed be used instead of them. For example, passing arguments:

bat, cat, dog=(2, 3, 7)
bat, cat, dog=[2, 3, 7]

# the former is probably used by the Python parser to do:
bat, cat, dog=2, 3, 7

This isn’t going to turn into a Java-harping fest, but I do want to point out that ArrayLists are bitches. Even with Generics, it’s still a paint to quickly setup lists within lists like I would do with Lua/Python/Ruby

Scope

Lua’s default scope for every variable is global. This does make sense for game scripting, but if I were so inclined to write, say an HTML rendering engine, I would be compartmentalizing every variable in sight.

-- the following is global
x=5

-- the following is local
local x=5

My OO sense tells me to use “local” everywhere in Lua. Even in Perl:

my $x=5

Must. Keep. Things. Local. We’re not using BASIC, are we?

Another thing that trips me up, as I remain a newbie in several languages at once is accessing a module/class/instance variable/method/class method.

C has this:

int a=something->apples;

Perl has this:

something::class_x.doodle(4);

And this:

something->drip();

C++ has this:

something::method_x(4);

Python uses dots for everything (my choice):

a=something.part.method_y(4)

I haven’t dug into Lua enough to learn about its ability to roll your own OO system, so I proceed with Ruby.

Ruby has this:

something.da() # yes, yes, I know the parenthases are uncessesary

And this:

something::class_x.da

And this:

something.class_x.da

What’s the difference? Please comment!

Cocoa’s API uses underscores like the developers are being paid by the character. _some_long_ass_method_that_starts_with_an_underscore(). There is a pattern that methods start with underscores if they take parameters. Bollocks. Nobody else does this, because it is stupid.

I believe that privacy for variables is pointless. It’s not really a security measure, as there are super super easy ways around the protections. In C++, you can overwrite the “private” keyword be declaring that “private” means “public.” And in Ruby, you can just define the class all over again with the “attr_accessor :some_var” method. Sure, you don’t want us programmers to screw up data in objects, but why give us monkeypatching on one hand and private data members with the other?

One of my projects was to recreate Liero in Python. I decided to make the weapons mod system simple. One way to make a new weapon quickly is to copy an old one, change the constants like THRUST and GRAVITY in the weapon .py file, and change the bitmap image. When the game loads the mod, the weapon class creates a new class with the same THRUST and GRAVITY constants. I thought they were class variables. No, they are not. I made the same mistake in Ruby, and realized that once one of these variables is changed in a subclass, the variable in a superclass is also changed. AAAAAH! Not good. There must be a way to make a tiny dynamic class for a weapon mod or user script or whatever, like but definitely not exactly this to be saved in WackWeapon.rb:

class WackWeapon
@@DAMAGE=40
@@THRUST=2.0
end

I’ve decided to instance_eval() my user scripts for Alchemy. Imagine that the class Recipe is already defined, and the following will be read into a new Recipe object:

@name="AdBouncer"

@whitelist=[
/http:\/\/www.admonger.com/,
/http:\/\/www.uglyads.com/,
/http:\/\/www.adrevenue.com/
]

def block(page)
page.links.reject! { |link| @whitelist.any? { |regex| link=~ regex } }
end

Instead of trying to load class variables, I just use instance variables. This setup does not allow a Recipe to extend another Recipe, though. Each must be made from scratch.

Core Library APIs

Python’s print() really ends up calling sys.out.write(). Java should add a print() that calls System.out.print(). That way, Java’s HelloWorld wouldn’t look like hell. public static void main(String[] args)? STFU.

I hate forcing paramater or return types anyway. I’m using this object to do what I want, now that object. I can’t waste my time telling the language which object I’m going to use. Screw that. I’ll use common sense plus comments plus the documentation to specify the paramater and return types, and nowhere else. The only caveat is overloading functions. Without specifying parameter types, there’s no way to actually do this. The first solution that comes to mind in Python is to make little functions that convert several types into the intended type:

# takes float
def do_thing(x):
if isinstance(x, list): _do_thing_list(x)
elif isinstance(x, int) _do_thing_int(x)
else: print x

# takes list
def _do_thing_list(x):
for e in x: do_thing(x)

# takes int
def _do_thing_int(x)
do_thing(float(x))

Thanks WordPress for making sure I can never properly display Python code blocks. Every attempt to insert spaces and tabs is thwarted.

Anyway, you can see some of the problems with trying to use the same syntax with different languages. Hopefully, purpose, then style demands the syntax of a language, rather than my biased and unlearned expectations of what a language should look like. I winced at snippets of Ruby code, and some things that still bother me will be resolved in future versions (Ruby’s getting real Char#ord, Int#chr, String#[i], and hopefully String#each_byte and String#bytes methods). Like tuples and lists, there always seems to be multiple ways to do the exact same thing. Should I use curly braces or do/end? I pick curly braces because they stand out against the otherwise largely alphabetic code. I can’t think of anything to use for block arguments besides pipes (|’s). When I do, Matz is going to hear from me!

One pitfall: In Python, “or” does the same thing as the old ||. “and” does the same thing as &&. But in Ruby, these cannot be used interchangeably. Statements that choose some value or nil must be phrased, “some_value || nil”. Trying to replace || with “or” will raise an error.

Terminology

Which brings up another point. Are things Errors or Exceptions? Be consistent. Among other things that were actually very surprising in Ruby are IO errors, which form some sort of error code rather than an actual Exception class. I guess any object can be raised, even stupid Errno:ENOENT’s.

Leave a comment »

Follow

Get every new post delivered to your Inbox.