1. Procedural design patterns?
- Posted by TheresNoTime Sep 26, 2013
- 2127 views
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:
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! :)
2. Re: Procedural design patterns?
- Posted by ChrisB (moderator) Sep 26, 2013
- 2085 views
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
3. Re: Procedural design patterns?
- Posted by TheresNoTime Sep 26, 2013
- 2057 views
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.
4. Re: Procedural design patterns?
- Posted by mattlewis (admin) Sep 26, 2013
- 2061 views
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
5. Re: Procedural design patterns?
- Posted by TheresNoTime Sep 26, 2013
- 2077 views
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.
6. Re: Procedural design patterns?
- Posted by mattlewis (admin) Sep 26, 2013
- 2097 views
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].
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
7. Re: Procedural design patterns?
- Posted by useless_ Sep 26, 2013
- 2093 views
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
8. Re: Procedural design patterns?
- Posted by ghaberek (admin) Sep 26, 2013
- 2060 views
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
9. Re: Procedural design patterns?
- Posted by jaygade Sep 26, 2013
- 2049 views
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.
10. Re: Procedural design patterns?
- Posted by BRyan Sep 26, 2013
- 2028 views
You also can use Matt's structures and 4.0 preprocesser
11. Re: Procedural design patterns?
- Posted by ghaberek (admin) Sep 26, 2013
- 2024 views
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
12. Re: Procedural design patterns?
- Posted by TheresNoTime Sep 28, 2013
- 1962 views
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