Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411696 Posts in 69399 Topics- by 58454 Members - Latest Member: roeyskatt

May 18, 2024, 07:40:07 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Programming Languages
Pages: 1 2 [3] 4
Print
Author Topic: Programming Languages  (Read 13012 times)
brog
Level 7
**



View Profile WWW
« Reply #40 on: December 24, 2008, 07:01:29 PM »

I was just trolling.. someone earlier said much the same thing about floats earlier on.  Really floats are great for what they do, but if you were to abolish one of floats and ints it would have to be floats.  No question about it.  Clearly ints divide fine, 5/2 = 2, and for the rare circumstances where you need to know the fractional part you can make a rational datatype from pairs of integers.

Quote
They also don't represent as large a range of values as floats
Now this I take exception to!  A 32-bit integer can represent exactly the same number of values as a 32-bit floating point number (actually slightly more, if you discount the NaNs and INFs).
And they do it in a much more useful fashion because you don't have gaps when the numbers are large.  You can iterate through all integers using ++i, adding one each time, but if you try the same with floats it'll get stuck somewhere where i+1 is approximated by the same float as i.
Logged
increpare
Guest
« Reply #41 on: December 24, 2008, 07:12:02 PM »

but if you try the same with floats it'll get stuck somewhere where i+1 is approximated by the same float as i.
There probably is some silly iterator for floats all the same.
Logged
BorisTheBrave
Level 10
*****


View Profile WWW
« Reply #42 on: December 25, 2008, 02:45:49 AM »

Range as in MAX_VALUE and MIN_VALUE, which are way better for floats.

And you cannot actually do the pair of ints = rational thing. Without cancellation, it only takes a few operations to get an overflow error, and with it is slow.

My approach for people I'm not sure are trolling or not is just to give short replies. I've seen some very stupid but genuine people on other boards. After all,
Quote from: H. L. Mencken
No one ever went broke underestimating the intelligence of the American public.
Logged
Bad Sector
Level 3
***


View Profile WWW
« Reply #43 on: December 25, 2008, 01:30:39 PM »

The best Object Oriented system (one that is much closer to the original idea about OO than C++ or Java is) is this:
Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MSG_NOTHING 0
#define MSG_CREATE 1
#define MSG_DESTROY 2
#define MSG_ATTACK 3
#define MSG_DIE 4
#define MSG_DAMAGE 5

typedef struct _object_t
{
    int (*proc)(struct _object_t* me, int msg, void* arg);
    void* data;
} object_t;
typedef int (*object_proc_t)(object_t* me, int msg, void* arg);

object_t* create_object(object_proc_t proc)
{
    object_t* obj = malloc(sizeof(object_t));
    obj->proc = proc;
    obj->data = NULL;
    proc(obj, MSG_CREATE, NULL);
    return obj;
}

void destroy_object(object_t* obj)
{
    obj->proc(obj, MSG_DESTROY, NULL);
    free(obj);
}

void send_message(object_t* obj, int msg, void* arg)
{
    obj->proc(obj, msg, arg);
}


int monster_proc(object_t* me, int msg, void* arg)
{
    switch (msg) {
    case MSG_CREATE: printf("a monster is created\n"); break;
    case MSG_DESTROY: printf("a monster is destroyed\n"); break;
    case MSG_ATTACK: printf("attacking\n"); break;
    case MSG_DIE: printf("ugh! dead...\n"); return 1;
    case MSG_DAMAGE: printf("woaaaaye!\n"); break;
    default: ; /* ignore other messages */
    }
    return 0;
}

int immortal_proc(object_t* me, int msg, void* arg)
{
    switch (msg) {
    case MSG_CREATE: printf("an immortal is created\n"); break;
    case MSG_DESTROY: printf("an immortal is destroyed\n"); break;
    case MSG_DIE: printf("i won't die that easy\n"); break;
    case MSG_DAMAGE:
        printf("your efforts are futile\n");
        send_message(me, MSG_ATTACK, arg);
        break;
    default: return monster_proc(me, msg, arg);
    }
    return 0;
}

int mouse_proc(object_t* me, int msg, void* arg)
{
    switch (msg) {
    case MSG_CREATE: printf("a mouse is created\n"); break;
    case MSG_DESTROY: printf("a mouse is destroyed\n"); break;
    case MSG_ATTACK:
        printf("squeak\n");
        send_message((object_t*)arg, MSG_DAMAGE, me);
        break;
    case MSG_DAMAGE:
        printf("squeee!!\n");
        send_message(me, MSG_DIE, NULL);
        break;
    default: return monster_proc(me, msg, arg);
    }
    return 0;
}

object_t* create_monster(const char* name)
{
    if (!strcmp(name, "mouse")) return create_object(mouse_proc);
    else if (!strcmp(name, "immortal")) return create_object(immortal_proc);
    return create_object(monster_proc);
}

void monster_attack(object_t* monster, object_t* target)
{
    send_message(monster, MSG_ATTACK, target);
}

int main(int argc, char** argv)
{
    const char* names[3] = {"mouse", "immortal", "foo"};
    object_t* monsters[32];
    int i;
   
    for (i=0; i<32; i++)
        monsters[i] = create_monster(names[i%3]);
       
    for (i=0; i<32; i++) monster_attack(monsters[i], monsters[(i*3)%32]);
   
    for (i=0; i<32; i++) destroy_object(monsters[i]);
   
    return 0;
}

It can do dynamic inheritance (just call another parent proc in messages you don't want to handle), encapsulation, interfaces (the MSG_xxx part), messaging (basically the whole thing is based on OOP by messages), abstraction (monster_proc can be used as an abstract entity) and even polymorphism if you use the MSG_xxx as an interface to actions.

And beyond all, there is nothing hidden from the programmer.

And its written in one of the most basic and simple languages: ANSI-C :-)
Logged

~bs~
Klaim
Level 10
*****



View Profile WWW
« Reply #44 on: December 25, 2008, 04:26:03 PM »

Wow!

That thread should be called "Programming Language Troll Fest" !  Gentleman

Logged

brog
Level 7
**



View Profile WWW
« Reply #45 on: December 25, 2008, 07:00:19 PM »

My approach for people I'm not sure are trolling or not is just to give short replies. I've seen some very stupid but genuine people on other boards. After all,
Quote from: H. L. Mencken
No one ever went broke underestimating the intelligence of the American public.

That is a wise and admirable approach, I respect it.  Fortunately for me, I'm not American, but I guess the point still holds.  (Actually, it's probably even more true if you replace "the American public" by "people on the Internet").

Anyway, sorry about the trolling.  When I see things I disagree with sometimes my trollish blood just takes over.
Logged
Batmanifestdestiny
Level 1
*


When life gives you lemons, make an internet craze


View Profile WWW
« Reply #46 on: December 26, 2008, 09:55:00 PM »

Here's my view on programming languages:

I've used BASIC, GML(a bit),ZZT-OOP, whatever the heck RPG maker uses, a fraction of FORTRAN, and I'm learning C++(can you tell I have no life?)  and I see it like this; dynamic languages are good for programmers(beginning or not) but are especially good for beginners, however, they may run a bit slower (one extreme case would be a platformer I made in ZZT-OOP, where it was a half second between hitting the key, and the player moving, because it was going through all the safety nets, trying to figure out what I wanted, and because I was a gotophile, apparently), whereas with static languages like C++, one semicolon out of place can screw the whole thing up, but they give you a bit more precisity(yes, that's a new word, folks!) and a bit more speed, though it's all based on the programmers preference.
Logged

"Sweet Sacajewea, Batmanifestdestiny!  We've struck GOLD!" -Joseph, Utah Wonder

You have to plagierize the Italian.
increpare
Guest
« Reply #47 on: December 27, 2008, 03:31:10 AM »

I've used BASIC, GML(a bit),ZZT-OOP, whatever the heck RPG maker uses, a fraction of FORTRAN, and I'm learning C++(can you tell I have no life?)
The only possible indicator of this to me seems to be the parenthetical comment.  Lips Sealed

Quote
and I see it like this; dynamic languages are good for programmers(beginning or not) but are especially good for beginners, however, they may run a bit slower
They always run slower that equivalent typed languages.  I mean, you'd have to think of something really screwed up that would be faster than it's statically-typed cousin.

Quote
whereas with static languages like C++, one semicolon out of place can screw the whole thing up,
I don't see how semicolon-placement enters into the static/dynamic debate.  PHP also has semicolons which, misplaced, cause everything to crash/misbehave.

Quote
but they give you a bit more precisity(yes, that's a new word, folks!)
no it's not

Quote
and a bit more speed, though it's all based on the programmers preference.
I agree with you here to some extent (though not to the extent, to which I'm uncertain if you're reaching, that certainly languages aren't more-or-less objectively better suited to certain tasks than others).

Excuse me for being a bit of a ; I have yet to have breakfast.
« Last Edit: December 27, 2008, 03:34:12 AM by increpare » Logged
nihilocrat
Level 10
*****


Full of stars.


View Profile WWW
« Reply #48 on: December 27, 2008, 09:45:40 AM »

code for Actor pattern

Yeah, the moment I saw that I thought "oh, I remember seeing this in some Stackless Python tutorials." I then read a bit deeper and realized "oh, I remember seeing this in ZZT's scripting language, ZZT-OOP." I'm betting this is the sort of system that Sweeney had running under the hood. I haven't realized until now how powerful the pattern is for creating games.

It's also interesting to point out, to those that might not be so jaded, that you can build an OO system like this in a non-OO language. The OO present in C++ and even Python is at its core just syntatic sugar and/or extra compiler checks. At its core, it's just as simple as passing a data structure representing an object to a series of functions that take it as an argument. For some reason this wasn't quite obvious to me when I was first learning C++.

I second that it's more "pure" because it's the pattern Alan Kay had in mind originally for OO.
Logged

Bad Sector
Level 3
***


View Profile WWW
« Reply #49 on: December 28, 2008, 04:49:37 AM »

I don't think Alan Kay had a pattern in mind when he thought about OO since patterns were thought much later (i believe). In any case i didn't had a pattern in my mind when i thought about this (although i mostly based it on Windows' messaging, which was based on Mac's messaging, which i believe was inspired a lot by Alan Kay's work given Kay was an Apple Fellow at the time).

Also when i looked up "Actor pattern" in Google the results didn't had much to do with what i wrote. The only similar thing i found is this slide which doesn't say much.

Can you point me to a page that describes this Actor pattern?
Logged

~bs~
increpare
Guest
« Reply #50 on: December 28, 2008, 09:58:01 AM »

Can you point me to a page that describes this Actor pattern?
I'd like to second this.  I find this interesting.
Logged
nihilocrat
Level 10
*****


Full of stars.


View Profile WWW
« Reply #51 on: December 28, 2008, 11:13:35 AM »

http://members.verizon.net/olsongt/stackless/why_stackless.html#actors

I might be misusing the term if it's not properly the Actor model.

My understanding is that they are basically just objects that can send or receive messages and perform actions based on those messages. The more I manage to program "everything else" into my games (audio, GUI, networking) the more I realize that message-passing between objects, via an event subsystem or via the Actor model or whatever you feel like, is probably one of the best ways of doing things. It does a great job of separating actions from all of the reactions that other objects need to make based on that action.

Instead of having to code complex behavior into the function that handles when something happens (like when a bullet hits a dude) you can just send a message out to some third party (like the World in this example) or to those directly involved, and they can figure out what needs to get done.
« Last Edit: December 28, 2008, 11:17:21 AM by nihilocrat » Logged

BorisTheBrave
Level 10
*****


View Profile WWW
« Reply #52 on: December 28, 2008, 11:17:01 AM »

Try this.
Actors is one of these words people use to mean an awful lot of things, but the general idea is actors have their own threads of execution, and communicate with message passing. Unlike threading, actors are generally split up by some notion of locality or persistence, rather than by task.
Logged
Bad Sector
Level 3
***


View Profile WWW
« Reply #53 on: December 29, 2008, 01:43:24 AM »

Interesting article. And its a "model" not "pattern" :-). A model is a general thing applied not only to programming languages but other things too (the wikipedia article mentions email as an example of the Actor model).

What i find more interesting is that while i didn't thought this as a system for concurrent applications, just yesterday a little before i went to sleep i was thinking that now i learnd about CUDA (see the blog article i wrote yesterday) i can probably write a virtual machine that runs small autonomous programs in CUDA kernels and each kernel being some sort of node that communicates with other nodes and the host (the CPU program) via asynchronous messages. In fact i had this "asynchronous communication" with messages for a while at the back of my mind but when you learn something new sometimes you explode from ideas :-).

But anyway thats just one of the ideas i had.

However, what i have in my mind while looks similar to the Actor model, it isn't the same. While i do use message passing, this sort of communication between nodes in a system is not necessarily the "Actor model". A difference is the notion of a central registry for the objects which provides knowledge for all objects (in Actor model, as described by the wikipedia article, actors only know about themselves and the actors they talker to). In the C example the registry is the linker who knows all the function names. Another difference is that when a message is sent, the sender waits for an answer, even if it means that the answer is that the message is ignored (nil answer), because this simplifies things greatly in a practical system (imagine if you had to ask of a monster's X coordinate for calculating the distance between it and some other object and you had to do it by sending a message and waiting from the monster to respond at some point in the future with another message that contained the answer). Which brings me to another point: the article doesn't mention what happens if an actor doesn't know about a message. The python example given in nihilocrat's link shows that an actor responds that it doesn't know the message and the way it is written looks like that it considers it as an error. In my design a sender doesn't know if the receiver will respond to the message or not and a receiver has to ignore a message if it doesn't know how to respond. This is intentional because of what i call "combined objects": that is objects which are made of other objects. A C example of a combined object, based on the C example i gave above is:
Code:
int combined_proc(object_t* sender, int msg, void* data)
{
    primalpha_proc(sender, msg, data);
    return primbeta_proc(sender, msg, data);
}
The "combiner_proc" object procedure can be used wherever a normal object procedure can be used, yet the way it acts is different than a normal object procedure's because it passes the same message and data to other objects (primalpha and primbeta). These other objects can contain incomplete logic, a some sort of building blocks, which once combined form other complete objects. An example in a game would be:
Code:
int gun_proc(object_t* me, int msg, void* data)
{
    if (msg == MSG_FIRE) { /* the entity fired */
        ... code to fire the gun animation ...
    } else if (msg == MSG_RELOAD) { /* the entity is reloading */
        ... code to fire the reload animation ...
    }
    return 0;
}

int exploding_gun_proc(object_t* me, int msg, void* data)
{
    if (msg == MSG_DIE) { /* the entity is dying */
        ... explode the gun ...
    } else return 0;
}

int running_away_monster_proc(object_t* me, int msg, void* data)
{
    if (msg == MSG_DAMAGE) { /* the entity is damaged */
        if (... health low...) ... run away ...
    } else return 0;
}

int monster_proc(object_t* me, int msg, void* data)
{
    if (msg == MSG_THINK) { /* periodic think update */
        if (... player is near ...) ... set state to attacking ...
    } else if (msg == MSG_DAMAGE) { /* the entity is damaged */
        ...update health...
        if (... ran out of health ...) send_message(me, MSG_DIE, NULL);
    } else ...other stuff...
    return 0;
}

int panda_monster_proc(object_t* me, int msg, void* data)
{
    if (msg == MSG_CREATE) { /* the object is created */
        ... setup panda ...
    }
    gun_proc(me, msg, data);
    exploding_gun_proc(me, msg, data);
    running_away_monster_proc(me, msg, data);
    return monster_proc(me, msg, data);
}
In this case the "panda_monster" is a combination of the incomplete objects objects gun, exploding_gun, running_aray and monster. With a large number of incomplete objects and different combinations, you can create a variety of complex objects. You might know this sort of "incomplete objects" as "behaviors", especially if you used Construct which is based on them (although much like message passing, behaviors are not tied to a single model and can be implemented in a variety of ways).

Of course since combined objects are basically C functions, the "combination" can be done in a variety of ways with the combined object inspecting the message and refusing to pass it in the incomplete objects or modifying it before passing it. The incomplete objects themselves can modify the message or even send messages to themselves. For example the "running_away_monster" object when decided to run away could send a MSG_AFRAID message to itself. The "running_away_monster" wouldn't respond to the message but another object, say "crying_monster" could catch it and setup the monster's state to start crying or a "hiding_monster" could catch it and make the monster semi-transparent (hide it). A combined object could use any combination of "running_away_monster", "crying_monster" and "hiding_monster" to introduce variety to the behavior of an entity and all it would need is a 3-4 lines of code in the combined object's code.
Logged

~bs~
increpare
Guest
« Reply #54 on: December 29, 2008, 02:21:01 AM »

Interesting.  I will definitely consider coding an actor (or at least message-sending)-based model to support my next project.

Two questions about working within this model (that might be answered in the wiki article, that I don't quite have the time to read through)
1: I take it that it would be considered bad form to have an actor be able to directly 'broadcast' a message to every other actor?
2: Would it be bad form for an actor to store pointers to other actors it has previously dealt with in its own data structure, for later use?  It seems like it would.

Would there be enough chitchat potential for having a thread about programming patterns/models specifically as they would to games?  I've mainly been investigating FRP recently, which is very interesting, though still pretty obscure to me (and very much under active development).

One other point about static typing: it's not strictly necessary for statically typed languages to require users to hand-type everything.  There is such a thing as type inference, where the user doesn't need to specify the type of a variable if it's obvious from the context.  OH, I see D has this.  Cool.  (as probably will C++0x).  The following quite interesting video on F♯ (which will be shipped as part of visual studio 2010) reminded me of this fact.
« Last Edit: December 29, 2008, 02:24:05 AM by increpare » Logged
BorisTheBrave
Level 10
*****


View Profile WWW
« Reply #55 on: December 29, 2008, 03:23:24 AM »

There probably is an Actor pattern too: an implementation of Actors for languages which don't support it. Like Bad Sector's, only OO, and with a statemachine to emulate a thread of execution you can suspend at certain points. Pretty much all patterns are there just for languages that don't support a particular design, imho.

By the way, Bad Sector, you are re-inventing the wheel somewhat, I'm not sure if you are aware of this. Aside from the fact you are doing OO in a non-OO language, obviously, you might want to look into "mixins", which are a dynamic language way of implementing something similar to your combiner objects.

If you allow direct returns instead of message passing, you are breaking the model somewhat. You've lost your nice concurrency properties, and ability to nicely separate the actors onto different processors or machines.
What you really want it a send_messsage_and_suspend_until_reply_recieved function, but of course that is impossible to write in C. This is why people generally use a language better suited for this sort of thing. Erlang is the classic example, but I've looked at Stackless python a bit, and that seems a solid example for game making (EVE Online is written in it).

In Stackless, you have channels which are bidirectional communication between actors (threadlets), and if you read from a thread prematurely, you will merely suspend until something is written to it. It can also handle many readers/writers to the same thread, which is how you should do event broadcasting, increpare (i.e. events are done based on subscription). And best of all, it can do suspend/resume based implicitly, based on ordinary function calls and yield syntax, which makes writing actors very similar to ordinary imperative code.

Increpare:
It is bad in the actor model to have any global stuff (e.g. broadcasts), as it breaks concurrency. Instead, you should create an actor to represent it, and still communicate via messages. Actors should be passed references to such global actors on creation. Your event handler actor would be such an actor.

Yes, it is bad form to store pointers. You want to abstract away the mechanism of a reference to an Actor, as you may later want Actors to reside on different machines, or be cached to the hard disk when inactive, etc (for when you are writing an epic MMORPG). Have some type actor_ptr that handles it. But yes, you should absolutely store references to other actors, just be aware that they might be dead by the time you send the next message, for whatever reason. In stackless, channels themselves serve as references to other actors.
Logged
nihilocrat
Level 10
*****


Full of stars.


View Profile WWW
« Reply #56 on: December 29, 2008, 09:16:55 AM »

You could also just make your actor log notable messages it's sent/recieved, and thus keep these references via the actor abstraction rather than through a language-level pointer.
Logged

Bad Sector
Level 3
***


View Profile WWW
« Reply #57 on: December 29, 2008, 09:35:51 AM »

@BorisTheBrave:
I'm not inventing anything, at least i don't try to. After i "invented" the linked lists myself out of need to get over the limitation of
Code:
var foo:array [0...30000] of something;
in Turbo Pascal (DOS era and 640k limit - or 256k practical limit if you wanted to execute other DOS apps in TP Tongue) and learned a while (one or two years) later that this is one of the oldest things in programming, i'm pretty much sure most things i come up with have been thought by someone else, probably one or two decades ago  Tongue

What i'm doing is basically evolving what i use now and then.

I don't really care about patterns, models, etc - i might take an idea from here and there but i'm not going to follow any rules about what is good or not. My primary goal is to make software that works and is good according to my standards Smiley.

In that sense, i don't care about losing the concurrency of the messages* if adding a return value makes the programming much easier and i wouldn't think twice about adding broadcasting if that would help me.

Also i believe that following patterns is a bad programming practice because in the long term considering some things as 'bad' limits your programming imagination and harms your problem solving skills. However that is another story for another topic and some people are very "religious" about their patterns  Roll Eyes  so i won't go into this.

In any case what i do is read from here and there bits (but rarely whole stories) about stuff -especially applied things- and try to form my own based on the task at hand Smiley.


(*=of course assuming concurrency is not a requirement)
Logged

~bs~
BorisTheBrave
Level 10
*****


View Profile WWW
« Reply #58 on: December 29, 2008, 10:10:16 AM »

No worries, Bad Sector, I'm not going to go all evangelical on you. I like patterns because people have thought carefully about them, and so they represent neat chunks of programming you can absorb. They are not, nor should be, a substitute for original work.

But after similar experiences to your linked list story, I've had a mortal dread of "re-inventing the wheel", as though I've done it many a time, I don't think I've ever made an implementation better than that which I could have found with half an hours research (when there is an answer out there, of course).

But I wouldn't be quick to only use a partial implementation of a known pattern. Actors are less of a worry admittedly as they are not a real pattern, but a model as others have pointed out. Nonetheless, cutting corners in patterns, e.g. by using vanilla returns, tends to come back to bite you in the ass. I'm not sure I could put together a compelling case, but I suspect the requirement in this case is there so you can scale up your actors with multiple threads, processors and computers, so not the end of the world for many uses.
Logged
nihilocrat
Level 10
*****


Full of stars.


View Profile WWW
« Reply #59 on: December 29, 2008, 12:11:58 PM »

This has made me feel a little like putting a tutorial together about the actor model and/or using event systems and message passing in general. It's one of the things which I hadn't learned very much of in programming classes or from online tutorials, but the clarity of the metaphor for the sake of games is almost on par with object-orientation.

My first games, after I had learned enough to draw things on the screen and push them around, didn't use any events at all and decided on things like counting score and respawning enemies by hard-coding behavior into the main program loop. Things are a lot more clean if you have a seperate message-passing system in place, and I don't think current educational material highlights this enough.
Logged

Pages: 1 2 [3] 4
Print
Jump to:  

Theme orange-lt created by panic