1. Procedural design patterns?

I recently became interested in object-oriented programming, because I began to sink in my own code. By studying design patterns, I came across the sentence:

CQS is well-suited to the object-oriented methodology, but can also be applied outside of object-oriented programming. There is nothing inherently object-oriented about the separation of side effects and return values, and so CQS can be profitably applied to any programming paradigm that requires reasoning about side effects. http://en.wikipedia.org/wiki/CQRS

Maybe my problem is not the use of improper language, but a improper use of language? Do you know any more patterns that are suitable for Euphoria?

I tried to find this information, but stupid Google feeds me links about OOP. Maybe you know some old book? Please, do not advise books by Donald Knuth! :)

new topic     » topic index » view message » categorize

2. Re: Procedural design patterns?

Hi

A comment about this and 'Prototype based programming' and OOP in general.

Aren't you over thinking this? The whole point about Eu is that its incredibly simple to use, so that even a non fegree level educated programmer like myself, who essentially programs in his spare time, can pick it up and use it.

Surely adding OOP, prototype based programming, procedural design constraints and so on would just add to levels of complexity. Don't we use some of these elements already without being aware of it?

At the end of the day, the result is the goal, not the process of getting there (to me at least). My vet database currently runs at about 50000 or so lines of code (not counted, so don't quote), is easily readable (I can pick up code years after writing it, and get an understanding very quickly) yet runs blisteringly fast using sqlite, is multi user, and continues to grow (if not regularly).

If oop (or other stuff) does take a hold, then please don't lose what we have now, for the sake of 'keeping up with the Joneses)

Chris

new topic     » goto parent     » topic index » view message » categorize

3. Re: Procedural design patterns?

ChrisB said...

Aren't you over thinking this?

Yes, this is the most likely option. Sometimes, when I see that I can not do something, I start looking for a new language, rather than figure out how to do it in the old language. However, I am embarrassed that such situations occur more and more frequently with increasing the size of the program.

P.S. For example, how to implement CQRS in Euphoria? I can not figure out how this can be done without the OOP.

new topic     » goto parent     » topic index » view message » categorize

4. Re: Procedural design patterns?

TheresNoTime said...

P.S. For example, how to implement CQRS in Euphoria? I can not figure out how this can be done without the OOP.

In fact, the code examples in the wikipedia link show you non-OOP code. Translated to euphoria here:

integer x = 0 
function value() 
  return x 
end function 
 
procedure increment_x() 
  x = x + 1 
end procedure 

I don't see why OOP makes this any easier or harder.

Matt

new topic     » goto parent     » topic index » view message » categorize

5. Re: Procedural design patterns?

mattlewis said...
TheresNoTime said...

P.S. For example, how to implement CQRS in Euphoria? I can not figure out how this can be done without the OOP.

In fact, the code examples in the wikipedia link show you non-OOP code. Translated to euphoria here:

integer x = 0 
function value() 
  return x 
end function 
 
procedure increment_x() 
  x = x + 1 
end procedure 

I don't see why OOP makes this any easier or harder.

Matt

Of course, I did not mean such a trivial example. Let x is the level of force of an object in the game (the hero, the monsters, the boss). Pseudo-OOP-Eu:

hero = clone(person) 
hero.lifepoints = 100 
for i = 1 to 100 do 
  monsters[i] = clone(hero) 
end for 
boss = clone(hero) 
boss.lifepoints *= 10 
--------------------- 
if monsters.count = 0 then 
  attack_boss() 
  if boss.lifepoints = 0 then 
    puts(1, "You saves FairyLand!") 
  else 
    puts(1, "Boss eats you! :(") 
  end if 
end if 

How to automate reading and writing multiple parameters of the same type? Use a sequence where the first integer is hero's lifepoints, the next 100 - monsters' lifepoints, and 102nd is the boss?

sequence LifePoints = repeat(100, 101) & 1000 
 
export fuction hit(integer who) 
  LifePoints[who] -= 1 
end function 

Thank you. I'd rather look into the OOP.

new topic     » goto parent     » topic index » view message » categorize

6. Re: Procedural design patterns?

TheresNoTime said...

Of course, I did not mean such a trivial example. Let x is the level of force of an object in the game (the hero, the monsters, the boss). Pseudo-OOP-Eu:

hero = clone(person) 
hero.lifepoints = 100 
for i = 1 to 100 do 
  monsters[i] = clone(hero) 
end for 
boss = clone(hero) 
boss.lifepoints *= 10 
--------------------- 
if monsters.count = 0 then 
  attack_boss() 
  if boss.lifepoints = 0 then 
    puts(1, "You saves FairyLand!") 
  else 
    puts(1, "Boss eats you! :(") 
  end if 
end if 

Sure. That doesn't seem much different than using sequences. So, boss.lifepoints becomes, say, boss[LIFEPOINTS].

TheresNoTime said...

How to automate reading and writing multiple parameters of the same type? Use a sequence where the first integer is hero's lifepoints, the next 100 - monsters' lifepoints, and 102nd is the boss?

sequence LifePoints = repeat(100, 101) & 1000 
 
export fuction hit(integer who) 
  LifePoints[who] -= 1 
end function 

Thank you. I'd rather look into the OOP.

There are multiple ways to do this. You could keep parallel sequences for lifepoints and whatever else you need. Alternatively, you could store each entity as an element in the sequence, so you might end up with something like:

sequence Characters = repeat(100, 101) & 1000 
 
export fuction hit(integer who) 
  Characters[who][LIFEPOINTS] -= 1 
end function 
 

These issues don't go away with OOP. Also, the new scoping for 4.0 facilitates similar functions to inheritance and encapsulation. So, you might have a base module, character.e that deals with common attributes of different kind of characters, (heroes, monsters, etc). And then various files that handle the more specific aspects of types of characters. The basic API could be exposed as public, with helper methods inside of character.e meant to be used by hero.e, monster.e as exports.

You could register routine_ids for the various routines that need to be specific for different types. This gives you some of the benefits of typical OOP polymorphism.

Matt

new topic     » goto parent     » topic index » view message » categorize

7. Re: Procedural design patterns?


You could "wrap" the characters in a timeslice using task.e, this would reuse the same code for each character, and keep separate variables for each. Of course you'll need task messaging if you want the monster char to tell the human he just got bit, where, and how much. Or tell the sword object that it's length is now half. I quit working on it when someone else began working on it, and made my code useless.

useless

new topic     » goto parent     » topic index » view message » categorize

8. Re: Procedural design patterns?

ChrisB said...

Aren't you over thinking this?

Agreed. It seems naive to start with a paradigm before learning a language. Once you understand how the language works then you'll understand how to apply certain paradigms to that language. Most importantly, you'll realize after learning a language which paradigms work and which ones don't.

-Greg

new topic     » goto parent     » topic index » view message » categorize

9. Re: Procedural design patterns?

Doing what you want to do in a pseudo-object-oriented fashion in Euphoria really shouldn't be that difficult, the main differences will be that you have to do some manual bookkeeping (keeping track of object instances), you have to manually specify a "this" parameter, and that you can't use dot notation.

  • Create a file for your class. The filename and default namespace is your class name. Many true object-oriented languages require this as well.
  • Create your class variables. You will need to keep your instances either in a simple list, or you could use more complex data structures such as stack, map, whatever. Heck, you could probably even use EDS if you needed to be able to save and restore your state.
  • Create your object data type and any enums or constants required to be used with them.
  • Create your class methods, such as "new", "delete", or any others which work on the class as a whole. These can be procedures or functions as required.
  • Create your instance methods, such as getters and setters and "copy", "clone", comparisons, etc. as required.
    • Instance methods should take at least one parameter corresponding to "this" object -- usually some key returned by the "new" method. This is your key into your object list (whether a simple list or whatever).
    • Some instance methods may take an entire object representation to work on, but this should be avoided if possible.

For inheritance, you just include the parent classes/files in your new class/file. Prototyping is kind of built-in, you can get pretty involved with copying classes, objects, and methods if you need to.

Avoid exposing any variables outside of your class file -- make them all accessible and modifiable by getters/setters and other methods. At the most, a particular method may return an object representation as a sequence or may take an object represented as a sequence as an input parameter, but again that should be relatively rare.

Note: I've never actually done any of this, but Euphoria has the tools built-in to do it.

new topic     » goto parent     » topic index » view message » categorize

10. Re: Procedural design patterns?

You also can use Matt's structures and 4.0 preprocesser

new topic     » goto parent     » topic index » view message » categorize

11. Re: Procedural design patterns?

jaygade said...

Doing what you want to do in a pseudo-object-oriented fashion in Euphoria really shouldn't be that difficult, the main differences will be that you have to do some manual bookkeeping (keeping track of object instances), you have to manually specify a "this" parameter, and that you can't use dot notation.

  • Create a file for your class. The filename and default namespace is your class name. Many true object-oriented languages require this as well.
  • Create your class variables. You will need to keep your instances either in a simple list, or you could use more complex data structures such as stack, map, whatever. Heck, you could probably even use EDS if you needed to be able to save and restore your state.
  • Create your object data type and any enums or constants required to be used with them.
  • Create your class methods, such as "new", "delete", or any others which work on the class as a whole. These can be procedures or functions as required.
  • Create your instance methods, such as getters and setters and "copy", "clone", comparisons, etc. as required.
    • Instance methods should take at least one parameter corresponding to "this" object -- usually some key returned by the "new" method. This is your key into your object list (whether a simple list or whatever).
    • Some instance methods may take an entire object representation to work on, but this should be avoided if possible.

For inheritance, you just include the parent classes/files in your new class/file. Prototyping is kind of built-in, you can get pretty involved with copying classes, objects, and methods if you need to.

Avoid exposing any variables outside of your class file -- make them all accessible and modifiable by getters/setters and other methods. At the most, a particular method may return an object representation as a sequence or may take an object represented as a sequence as an input parameter, but again that should be relatively rare.

Note: I've never actually done any of this, but Euphoria has the tools built-in to do it.

I've done this before and it can work pretty well. Here are some points from my experience.

  • Always declare one class per file, each with a matching namespace.
  • You can wrap multiple classes into a single include using public include.
  • You can use a map object as your base "type" for all classes.
  • Create setters and getters for all of your properties and store the values directly in the map object.
  • You can inherit from classes by public include-ing it in the new class file.
  • Parent class methods have to be generic enough to accept any child class.
  • Otherwise, override the method in the child class directly, and then call the "base" class method from there.
  • Use the unit testing framework to test all of your classes!

I've put together a brief example here: http://openeuphoria.org/pastey/231.wc

-Greg

new topic     » goto parent     » topic index » view message » categorize

12. Re: Procedural design patterns?

Interesting document - http://www.dossier-andreas.net/software_architecture/pac.html

I am currently thinking about how to adapt it for the euphoria. Of course, this can not be done just because it is the OOP-pattern. However it is possible to do something a little bit similar. "Abstraction" will be data and simple functions for accessing it. Implementation of these functions will be dictated by the data structure.

"Presentation" will be functions and procedures for accessing data in human-oriented way.

"Control" will perform two functions: the glue between the data and functions (for example, it may include a "memory" to store intermediate values), and the skeleton of the program. Since the first function is almost clear (sometimes it will be absent at all), but the second function is more complicated. We have to do something like internal bulletin boards or e-mail server for the "Controls". For example:

-- Abstract part 
sequence FairyLandMap = ... 
export function getFairyLandCell(integer x, integer y) 
  return FairyLandMap[x][y] 
end function 
 
-- Control part 
map CachedData = map:new() 
 
export function getFairyLand3x3(Coordinates) 
  sequence MeAndWhatISeeAroundMe = map:get(CachedData, Coordinates, {}) 
  if MeAndWhatISeeAroundMe then  return MeAndWhatISeeAroundMe  end if 
  for i = -1 to 1 do 
    for j = -1 to 1 do 
      MeAndWhatISeeAround &= getFairyLandCell(x+i, y+j) 
    end for 
  end for 
  map:put(CachedData, Coordinates, MeAndWhatISeeAround) 
  return MeAndWhatISeeAround 
end fuction 
 
-- Presentation part 
function HowManyWolvesAround(sequence Coordinates) 
  sequence MeAndWhatISeeAround = getFairyLand3x3(Coordinates) 
  return find(Wolves, MeAndWhatISeeAround) 
end procedure 

I showed only the "glue" function of the "Control". I've been thinking how to provide the function of the skeleton. I have some ideas, but they have not enough formulated yet. Maybe, something like a telephone exchange? Addition interesting document - http://en.wikipedia.org/wiki/Node_graph_architecture

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu