Non looping languages a mystery to me.

Community Forums/General Help/Non looping languages a mystery to me.

ando(Posted 2012) [#1]
Hi, I'm hoping someone can help me to understand what's going on with a non looping language like monkey.
With looping style like C64 and B3D I feel very comfortable because I can see what is going on as each line is being read and acted upon before jumping back to the start of the main loop to start all over again.

Since the C64 died years ago and the B3D party is starting to wind down thanks to its ties with DX7, I feel I should be looking for another language. I only code as a hobby but I would like to have the possibility of making something commercial even if it's a couple of years away.

Is someone able to explain it so that a newbie like me can feel comfortable within that non looping environment ?
Thanks. :)


Yasha(Posted 2012) [#2]
The simple answer is that you aren't writing the whole program, just functions for the program to call at pre-set moments. The language is set up with the expectation that it will be used principally for games or scripted movies, and thus supplies the render/update loop itself, since it can safely assume you will want it. That's all.

In an environment like iOS this is supplied by the OS framework, and thus is also far more efficient and integrated than any similar structure you could easily create yourself. The platform doesn't necessarily want you to have the kind of control you would with a B3D program, as it needs to be able to decide when to allocate resources to your program for best performance.


ando(Posted 2012) [#3]
Thanks Yasha, I've read your response about ten times and I think it is starting to sink in. :)
I'll have a play with the monkey demo over the next few days and hopefully get more comfortable with it.
Thank you.


D4NM4N(Posted 2012) [#4]
Monkey is a looping language.

the only difference is they have made the loop for you. You just fill in the important blanks just like you would in your own code.

This is more or less standard practice on OOP engines.


xlsior(Posted 2012) [#5]
The old-style programming like B3D uses it called "procedural", while Monkey is "Object Oriented".

Blitzmax supports both procedural and Object Oriented program structures.

More info:
http://en.wikipedia.org/wiki/Procedural_programming
http://en.wikipedia.org/wiki/Object_oriented_programming


(I know where you're coming from, personally I find it much easier to create procedural programs as well)


AdamRedwoods(Posted 2012) [#6]
if a looping language is a circle "O", then monkey is a figure eight "8".
I suppose some programs are as complicated as the olympic rings symbol, weaving in and out of one another.


D4NM4N(Posted 2012) [#7]
grr why is it when you press UPDATE twice by accident it double posts!

its a BUG! :D

Last edited 2012


D4NM4N(Posted 2012) [#8]
@Adam

Not at all. If B3d is an "O" then monkey's mojo is more like a "C" (basically you only need to code half the circle! ;D)

it is actually MORE simple than in max or B3d. Basically in B3d your structure (-might-) look something like this:
(and this is relatively tidy code for b3d considering some horrors you see about!)

;Load and initialize everything most likely as ugly globals.
Initialise()

;--------  THE MAIN LOOP
while not quit
      ....
      ....
      //you probably have some tween/delta timing code here too
      //and perhaps setting some vars from reading keyboard/mouse?
      ....
      ....
      updateGame()
      render2D()
      flip
end while
;----------- END LOOP
 
function initialize()
      graphics3D....
      lots of initializations code and loading stuff. (Often seen all jumbled together in same place)
end function

function updateGame()
    updateLevel()
    updateHero()
    updateCollisions();
    etc...
endfunction

function render2d()
    drawLevel()
    drawHero()
    drawScore()
   etc...
end function

function updateCollisions()
       whatever code to perform collisions etc..
end function

etc........


All monkey's "mojo" engine/framework gives you an "App" class with few overridable methods meaning you actually need less code, and it is a lot more organized.

Think if you could just make a "main" b3d file with ONLY your 3 primary methods for:

"Init"
"UpdateGame"
"Render2D"....

rename them respectively:

"OnCreate"
"OnUpdate"
"OnRender"

And it looks more like this:
 
Class GameApp Extends App

  Field hero : CHero
  Field level : CLevel
  Field collisions : CCollisionManager

  Method OnCreate:Int()
        //Same as your initialize function above!  In this case though, all level and hero init code is tucked away tidily in level/hero classes. 
        //This is in a special part of the classes' code called a "constructor" which is basically a bit of code that fires 
        //when you call "new Level()" . This makes the code nice and tidy and very readable.

        level = new CLevel()  
        hero = new CHero()    
        collisions = new CCollisionManager(level , hero)
  End
 

  ///------------------------------this is your managed loop-------------------------
  Method OnUpdate:Int()
        //Same as your update function, but in this case runs the update -methods- inside the classes' code.
        level.update()
        hero.update()
        collisions.update()
  End
 
  Method OnRender:Int()
        level.render()
        hero.render()
        drawScore()
        etc...
  End
  //----------------------end of managed loop-------------------

End




IMO it is actually -easier- for noobs to understand. 3 methods to explain what they do and what they should be used for. They do not need to see what is going on in the "App" base class, they are simply overriding the 3 essential methods from "App" needed to do stuff.

Last edited 2012


therevills(Posted 2012) [#9]
@Dan, your Monkey example is using Mojo which is a framework which has the OnUpdate loop... When you are using just Monkey by its self you still have to do the loop yourself.


D4NM4N(Posted 2012) [#10]
lol sorry you are right, I should have been clearer. I just assumed by the original post that is what he must mean (kind of the out of the box way so to speak).
I have edited the above to say Monkey (mojo)

TBH I have not really played with monkey without mojo

Still I think it kind of helps / explains to the OP that there is no "non looping language like monkey" .

:)

Last edited 2012


ando(Posted 2012) [#11]
Thanks for the info people. After more then 20 years of coding a certain way, my head is pretty hard wired that way now. But I do believe you can teach an old dog new tricks, it just takes longer.

Thanks alot, this is all very helpful for me and I'll get there eventually. :)


D4NM4N(Posted 2012) [#12]
I know what you mean, I started out in many 8bit basics pascal and C, all procedural.

However after learning OOP concepts I never went back to procedural coding, and after a week or two of head-scratching and reading it all became clear. Once you start using these concepts you will wonder how you got by without concepts like Classes, inheritance, overriding etc.. which all sound complicated but are extremely simple when you get your head into them.

I highly recommend learning max or monkey because unlike a lot of oop languages the set-up-and-go requirement is so easy, and the concepts and structures are pretty much the same in any OOP language be it Java, C++, C#/VB etc..

Last edited 2012


Yasha(Posted 2012) [#13]
Y'know there's nothing in the original question that's really related to OOP at all... the entire provided-event-loop paradigm can be achieved with only function pointers (in fact, is achieved with only function pointers in most implementations), and in fact doesn't take advantage of classes in any way.


ando(Posted 2012) [#14]
Let me come at it a different way.

If I use a simple procedural example like this-

Graphics 800,600,16

Color 250,50,50

Repeat

  Plot MouseX(),MouseY()

  If KeyDown(28)
    Color Rnd(1,255),Rnd(1,255),Rnd(1,255)
  EndIf

  Delay 5

Until KeyHit(1)

End


Can someone please convert this to non procedural code, but that's not what my spaghetti brain wants to know.

How does the computer look at your version of the code , I mean step by step and then what happens after it's looked at it all once.
Please forgive my ignorance but my darn brain keeps trying to see things procedurally.

PS. I'll just be sitting on the dirt in front of my cave and clubbing away at my stone keyboard until I randomly get something to work. :)


Yasha(Posted 2012) [#15]
You'll understand this much more easily if you first think through what your example program really is, and what happens when it runs. i.e. How does the program start? How does it mark the beginning of the script you want to run?

The (grossly oversimplified, not necessarily literally accurate!) answer is that a procedural program is in a lot of ways just a list of functions. The finished program contains these functions and an index list to find them.

"But wait, I didn't define a function!" Oh but sir, you did - just without knowing it. Blitz3D wraps all the code in the outermost level in an "invisible", implicit function that will be exported under the name "main" (or something similar to that). This function works just like any other - it accepts arguments and has a return value.

The point of all this rambling is that the program can't simply "start at the beginning" somehow: instead, once the OS has loaded your program, it has to lookup the "main" function, call it with arguments, then wait for a result, in exactly the same way that your program might internally call a function you defined. So in some ways, what your program really is is a library that exports just the one function, to be called by the glorified event loop that is the OS.


So the matter of scaling this up to Mojo code (sorry, totally forgot earlier about the distinction between Monkey and Mojo) is now that you are just creating a library of three (is it three?) functions instead of just the one: an init function, to call before the loop, and update and render functions to call within it. The "hidden" part of the program has expanded to provide more features, but its relationship to the parts that you get to write is fundamentally the same. Where before the OS loop called your whole program, now the program outer-level loop calls the interesting parts of your code.


And again, this issue has nothing to do with the procedural/OOP distinction (except that in Monkey this stuff happens in the App class - but that's very much implementation-specific and you don't need to understand it to grasp the design concept).


D4NM4N(Posted 2012) [#16]
What ^he^ said.

Your code in one of many possible objective forms might look like:

B3dScreen screen = new B3dScreen();
Input input = new Input();

screen.setGraphics (800,600,16)
screen.setColor(250,50,50)

Repeat

  screen.plot (input.getMouseX(), input.getMouseY()

  If input.isKeyDown(28)
       screen.setColor (math.rnd(1,255),  math.rnd(1,255), math.rnd(1,255))
  EndIf

  system.delay(5)

Until input.isKeyHit(1)

End

-In other words pretty much the same. :)

------------------------------------------------------------

To understand a "class" in it's straightforward form:

Take a simple b3d type with 4 fields/variables.
Type TCreature
    field  handle%
    field  x#=1
    field  y#=1
    field  z#=1
 End type

Then you make a new instance of this type in the normal way:
creature.TCreature= New TCreature
Which returns a "reference pointer" to that "object".

^This^ is already using a simple object oriented concept. It is basically "an instancible(instance-able?) multi type data object"
Which can be accessed like so:
creature\handle = LoadEntity(file);
creature\x = 10.0;
creature\y = 10.0
creature\z = 10.0

However to control what it does you need to do it all from "outside".
eg:
MoveEntity(mytype\handle, mytype\x, mytype\y, mytype\z);

This is where "methods" come in. A method is pretty much the same thing as a function except it belongs inside the "scope" of a class.

Now we can turn it into a simple class using a conceptual "B3D style"syntax and you could have something like:
 Class CCreature
    field  handle%
    field  x#
    field  y#
    field  z#
 End Class
And look at that it is the same! And you could use it in the same way.... but lets not!

Instead lets add some methods to do something:
 Class CCreature
    field  handle%
    field  x#
    field  y#
    field  z#

    Method initialize()
          handle = LoadEntity(file);
          x = 10.0
          y = 10.0
          z = 10.0
    End Method

    Method move(x#,y#,z#)
          MoveEntity(handle,x,y,z)
          this\x = EntityX(handle)
          this\y = EntityY(handle)
          this\z = EntityZ(handle)
    End Method
 End Class

Note the "this" identifier (sometimes called "self") which basically refers to the instance of the class you are working with. This is not actually -needed-, but it is this in this case to know the difference from the "x" parameter coming in and the creatures internal field called "x".
-(Of course you could always call parameter x something else and drop the "this" ! :)

Now all your "outside" code needs do is:
creature.TCreature= New TCreature
creature\initialize()
creature\move(x,y,z)

We have now gone from a boring storage type to a type (or class) that can now initialise and control instances of it's-"self" from the inside.



...And that's it... a class in a nutshell !



---------------------good so far?... now the next bit--------------------------------

When you hear people talking about "Inheritance" and "Overriding" it is simply the fact that they have another class (a "base" class, sometimes called a "super" class) acting as a foundation for another. (and as it's namesake sugests... inheriting it!)
look at this:
Class CMonster extends CCreature
End Class

Class CHero extends CCreature
End Class

These new classes will have everything our previous class "CCreature" has (handle, x, y, z ,move() etc..) because it "extends" ("inherits") CCreature.
This means we do not have to declare them again as they are already there (remember, monster -is- a creature).

-So you could now say with full "genetic" accuracy:
our "hero" is a type of "creature".
our "monster" is also a kind of "creature" but is different to the hero.


-But- perhaps we want out monsters and heros to move differently to the basic creature and each other.
Class CMonster extends CCreature
      Method move(x#,y#,z#)
           ....do some special movement......
      End Method
End Class

Now monster will do everything creature can do, except when you call move you will "override" the base method and do something new.

You can also include the "base" (creature's) move method as well by using something like:
Class CMonster extends CCreature
      Method move(x#,y#,z#)
           ....do something special before calling move in the base class.......
           base\move(x,y,z)
      End Method
End Class


This is basically what the Mojo framework is allowing you to do to it's "App" class!

Also, you need to understand that in most OOP languages -everything- can be a Class or class instance, even the "Application" itself, and almost every "command" you use is simply a method in some other, class.
Most languages come with a huge host of included classes, which cover everything from drawing graphics and fileaccess down to handling strings.

There is a fair bit more to it, but if you can get your head round the above, then the other stuff you hear people yapping on about (like; polymorphism, interfaces, abstraction, constructors, namespaces, protection levels, static members, serializing etc....) would quickly make sense too, despite their horrific sounding names :D.
However you do NOT -NEED- any of these more advanced concepts to use monkey or max!!! (or java, c# etc for that matter!)
-The basics i describe above is more than enough for starters!


Here is some more reading if you are interested (it is Java, but it is the -concepts- that are important, not the syntax!):
http://docs.oracle.com/javase/tutorial/java/concepts/


NOTE: Most languages use "." instead of "\" to access object & structure members (Monk/BMax being no exception)
-B3d's use of "\" for this is actually fairly unique. I have just used a \ and b3d style for familiarity, meaning the code above is purely conceptual .

Last edited 2012


ando(Posted 2012) [#17]
Thanks, that's a big help there. I'm glad I have an understanding of Types otherwise I would have been totally lost.
Even though I have only just scratched the surface, I'm feeling alot better about it now thanks to all this help.
It took me over an hour with monkey to make a black screen with a red rectangle following the mouse. :)
Now I need to find a good list of commands.

Thanks again.

And I'd like to totally blame my daughter for my slow learning. She's on the other pc looking at pictures like this.(How can I concentrate) :)




D4NM4N(Posted 2012) [#18]
:D

that is awesome!



PS: Try and stay away from the idea of a general "list of commands" think more of a list of "things" (or "objects") that you can tell what to do.

For example where before you looked down a massive endless command list for:
"OpenFile"

instead think.. "ok the object i want to work on is a file, so the class may well likely be called File or something similar"

Then look in File classe's docs and you will likely see:
open()
close()
read()
readLine()
etc...

only together do they make your "command":
file.open()

it is like:
noun.verb :D

Last edited 2012


ando(Posted 2012) [#19]
Thanks D4NM4N, much appreciated. And thanks to all those that helped.
Now the Monkey/Mojo code won't look so alien to me.

If the right description is modular, I tested Just Basic a couple of years ago and I used Goto at the end of my code to create my familiar loop. Being modular, this was a no no and I got some wierd results.

Back to searching and testing and eventually found B3D. This suited my preferences perfectly. But because of the dreams I have for the next 5 or maybe 10 years, I found another basic very much like B3D (NB) so I think I'll be buying that one because that will be relatively easy for me to slide in to.

I also think Monkey would be a good purchase because that would open a lot more doors for me (being multiplatform) and I will enjoy learning the new coding methods (well, new for me) :)


D4NM4N(Posted 2012) [#20]
Glad you made some sense out of it.... I have no fingerprints now :D

Anyway good luck with monkey, i reckon it is a great choice for a first Oops language...
-and it will open doors because practically every oop language (with the possible exceptions of C++ and Obj-C) will make a LOT more sense.

I used Goto at the end of my code to create my familiar loop
Please do not swear on a family forum!
;D

Last edited 2012


ando(Posted 2012) [#21]
LOL, I showed some of my "code" a while ago and got a strong impression that I should have also suplied sick bags. :)


Steve Elliott(Posted 2012) [#22]

Glad you made some sense out of it.... I have no fingerprints now :D



Haha, but you did a good job of explaining OOP though. I think this would have helped a few peeps.


_PJ_(Posted 2012) [#23]

LOL, I showed some of my "code" a while ago and got a strong impression that I should have also suplied sick bags. :)




I wouldn't worry so much, unless your code is intended for someone else to use or work with ;)

I'm horrendously embarrassed with some of my earlier stuff, even some awful entries I put on the Code Archives in years past...


ando(Posted 2012) [#24]
Thanks PJ, a little confidence boost is quite handy now and then.

But to be honest, I can see the point of experienced coders and yet at the same time I am very stubborn. If it works for me then I am happy to keep doing it that way. I find it's more important to write bug free code than write something pretty. I just want the finished thing to do what it's supposed to do. I suspect in future when I look back on my old code I will either want to laugh or cry. :)


Steve Elliott(Posted 2012) [#25]

I find it's more important to write bug free code than write something pretty.



Then you've missed the point of OOP. Chasing bugs in a procedural, global variable mess is far harder than a well designed OOP game framework. Once you've built each self contained class, basically the game takes care of it's self and bug free code is much more likely.


ando(Posted 2012) [#26]
Yeah thanks Steve, I've had that pointed out before.
When I start coding in Monkey, I'm sure I'll pick up the proper way.

My comment above is related to B3D and how it allows me to code the way I like, the way i'm used to and the way that is easy for me. I don't expect anyone to see it my way but a long mess of spaghetti code with if this and if that all the way through it, well, to me it looks more like a beautiful smooth flow. I said I was stubborn. :)


Steve Elliott(Posted 2012) [#27]
Haha, oh I'm a procedural programmer at heart ando, so I do understand. It takes a while to get used to OOP if you've always programmed procedurally.


Jesse(Posted 2012) [#28]
I used to program procedural until I bought Blitzmax. I had looked at OOP before but was not able to figure it out until I looked at the first Blitzmax OOP tutorial. After that, I dumped procedural programming. Now almost all of my code is OO. There are things I still don't know and I can't say that I am really good at it but it works really well for what I do.


D4NM4N(Posted 2012) [#29]
Then you've missed the point of OOP. Chasing bugs in a procedural, global variable mess is far harder than a well designed OOP game framework. Once you've built each self contained class, basically the game takes care of it's self and bug free code is much more likely.

Agreed.
Also non-strict languages like B3D are by comparison -much- more difficult to debug because of the non-strict, single-scope nature. The fact you do not have to declare variables makes for some very "dangerous" code sometimes.

eg:
myVariable=1
.
.
1000 references to myVariable
.
.
x = myVarlable    <-----this error could leave you scratching more than headlice!
.
.
1000 more references to myVariable
.
.

Some people put everything global in a "global" type which is a good practice in b3d as it makes them strict, but if you are used to using types for most things rather than global variables then you are already a BIG step up the oo ladder anyway.


I'm horrendously embarrassed with some of my earlier stuff, even some awful entries I put on the Code Archives in years past...
I think we all suffer the cringe factor. It is simply a part of your personal development as a programmer (basically if you can look at your old code and criticize it then you are getting better at it!).
It is a bit like old photos when you think WTF was i wearing... and what is that creature sitting on top of my head :D

Last edited 2012


ando(Posted 2012) [#30]
Speaking of .....
I'm horrendously embarrassed with some of my earlier stuff


When I first found B3D I wanted to know how good it was before I even knew how to use it. I was still full of C64 thinking. Like, where are the bloody line numbers, what's endif etc etc...

I wanted to write a small test, so....



D4NM4N(Posted 2012) [#31]
nice!

(shudders and heads for the bottle of scotch grateful that it was not a debug request) ;D


ando(Posted 2012) [#32]
Ha ha ha...Hey, what are you talking about ? No bugs there mate, It's a masterpiece of um....um...well a word hasn't been invented for it yet. I could have called it primative 10 years ago but these days I'd have to use a stronger word than that.
Since beauty is in the eye of the beholder and some people will even like buckets of paint thrown at a wall, umm, let's go with "artistic". ;)

PS, I've even seen an elephant paint before but I don't think I'd hang it on my wall. :)


Adam Novagen(Posted 2012) [#33]
Actually your code looks quite good from where I'm standing; just add a few meatballs and some marinara sauce, and it'll make a wonderful plate of spaghetti! :D


ando(Posted 2012) [#34]
Thanks Adam, I couldn't stop myself from laughing.... :S
The sad part is.... you're quite right.

Last edited 2012


Steve Elliott(Posted 2012) [#35]
omg goto (shudders). :O


Adam Novagen(Posted 2012) [#36]
The sad part is.... you're quite right.
I think we've all been there. No one's a perfect coder from day 1; some of us learned in the C64 era, like yourself, where Goto was mandatory. Some of us, like me, learned slowly in Blitz even in our early days from that so-useful-but-also-so-questionable book Game Programming for Teens, which gave me a lot of the basic principles of programming but also gave me a LOT of bad habits and practices.


D4NM4N(Posted 2012) [#37]
a teacher way back in the dark 80s once told me that every time i used a goto i should be thinking "-how- can i do the same stuff with a gosub".
He was 100% bang on right (although it was not always possible as adam says :D)

then a few years later i saw the "function" for the first time.... (with parameters and return values!) and soon after, lo and behold i discovered the "struct" (basically a very early precursor "b3d type" still much in use and pretty much the same thing).
The clouds cleared and a ray of light came down, acompanied by an 8bit sampled orchestral voice of "電電電電電電電HH!"

'Twas the early building blocks of "oop"... (sniff)

I think C++ (and Obj C?) started to (really) take off +/- that same year (1989-90-ish), although it had already been around for 5-6 years.

Last edited 2012


ando(Posted 2012) [#38]
I think a good first step for me to move out of the dark ages would be to start using functions. So far I've avoided them because it was easy to get by without them. But I can see that I am limiting my way of thinking, so If I get some spare time over the next few days I will try to "modernise" that little SMEG (2D Tron) program just above and hopefully modernise my head a bit. :)

It's only a small program so it should be pretty easy and a good learning experience. I have not passed info back and forward before like you do with functions so that's what I am first going to have to come to terms with and I think that is exactly why I have been avoiding it.

I'll not complain if anyone wants to put a little example of passing info to and from functions. Thanks.


Yasha(Posted 2012) [#39]
a little example of passing info to and from functions


Thusly:

Function myFunc#(a#, b$, c% = 0)    ;Declare variables for the values you want to pass in here, potentially with constant starting values
    Local d# = a / Len(b) * (c + 1)    ;Variables within the function aren't visible outside it
    Return d * 5    ;Once done, send the value out again with Return
End Function

Local val# = myFunc(6.2, "FOOBAR!")   ;If we provided a starting value for one of the args, it is optional

;The value 4.42857 is now in 'val'


A function body can contain any code structures you like, with the exception of some top-level definitions (can't contain other functions, type definitions, or global declarations), so you aren't limited to doing maths with them.

Much like a simple subroutine, the function ends when it hits a Return statement, except that in this case Return takes a value of the type specified after the function name (see where it says 'myFunc#' above, specifying # for the return). The value is optional (as is the Return statement - you can just let the function run to its end and it will return a zero).

The thing that separates functions from simple subroutines is the matter of scope. Within a function, the local variables in the rest of the program are invisible. The local variables within the function are also invisible to other functions, and to to the outer program. This provides very simple "encapsulation": you can write the code in the function largely without worrying about what is happening elsewhere (and what those names are doing, and so on). Only globals are visible within and without functions, which is why you should use them sparingly - this restriction on seeing variables elsewhere is a very good thing!

This also extends to recursive function calls: if a function calls itself for some reason, or it calls another function and then that one calls the first one again, there are now two separate copies of all of the local variables for the function. So each time a function is invoked, a new set of locals is created; and they are gone once it ends (i.e. next time they will have all-new zeroed values).

(There are also other ways to pass values in and out of functions, but they require you to be comfortable with types and objects, so forget those for now.)


...this talk of "scope" may seem confusing, but if you can believe it - those couple of paragraphs above are all you need to understand to completely understand functions and procedural programming!

So if anything about them is unclear (which, going by my track record in this thread, most likely is the case), do ask: that's the whole syllabus up there.

Last edited 2012


ando(Posted 2012) [#40]
Thanks Yasha, and I know it's really my track record or lack of... :)

I always have a problem with having to read instructions over and over until it slowly starts to make sense for me. Not until I use it in a practical sense will the learning curve finally take off and then I'll see how darn simple this was in the first place. Your help is greatly appreciated.

Last edited 2012