1. fake class in OE
- Posted by katsmeow Feb 22, 2021
- 1389 views
Just brainstorming here, because it's gnawing at me...
A fakeclass.cow.e , wherein there's global functions setclass() and getclass() (and maybe some other stuff), called like
Success = setclass("cow1","color","brown")
such that "cow1" is an enumerated item in list1 , "color" is the same enumeration in a list2 , "brown" is in another list. List contents can be out of order, as long as they stay synchronized. You cannot set parameters on cows flying, because flying is not in list2. You can search for brown cows by looking at the color list. You can set cow12 walked a mile today (based on GPS, to correlate to milk production), but the embedded function of walking() (found in list2) is going to see if the where and how fast is within parameters before accepting it.
ListOfParameters = getclass("cow","walking")
The goal of this was only to re-use the "object" cow.e for all cows, and make code run that's exclusive to and shared with all cows. It can be copied over and used for goats too. The lists can be saved to hdd between runs. I think it meets the definition of class, even though it doesn't use the designed syntax of other languages.
Kat
2. Re: fake class in OE
- Posted by Icy_Viking Feb 22, 2021
- 1426 views
Just brainstorming here, because it's gnawing at me...
A fakeclass.cow.e , wherein there's global functions setclass() and getclass() (and maybe some other stuff), called like
Success = setclass("cow1","color","brown")
such that "cow1" is an enumerated item in list1 , "color" is the same enumeration in a list2 , "brown" is in another list. List contents can be out of order, as long as they stay synchronized. You cannot set parameters on cows flying, because flying is not in list2. You can search for brown cows by looking at the color list. You can set cow12 walked a mile today (based on GPS, to correlate to milk production), but the embedded function of walking() (found in list2) is going to see if the where and how fast is within parameters before accepting it.
ListOfParameters = getclass("cow","walking")
The goal of this was only to re-use the "object" cow.e for all cows, and make code run that's exclusive to and shared with all cows. It can be copied over and used for goats too. The lists can be saved to hdd between runs. I think it meets the definition of class, even though it doesn't use the designed syntax of other languages.
Kat
I like this idea. Perhaps once struct supported is added, this can be added next. Or a feature to be added in the future?
3. Re: fake class in OE
- Posted by ChrisB (moderator) Feb 23, 2021
- 1315 views
Hi
I don't know, this doesn't look like it's making things simpler or easier to use, and definately looks more pythonesque. Of course I wouldn't have to use if I didn't want to, but would it pass the readable code by someone else in 10 years test?
Cheers
Chris
4. Class/Interface/Contract -- Re: fake class in OE
- Posted by mitgedanken Feb 23, 2021
- 1329 views
I hope my english is ok.
--[ <built-in> --[+ About An Interface --- --+] interface Class --[ About A Contract -- a "contract name" is optional, -- it is not to be the same name as the routine or variable. -- could be used for error reporting. -- If a contract is not satisfied an error will occur (aka ##error:crash()##) -- example: (# is like : for namespace. I choose that to differ from namespaces -- i.e. instead of ::) -- sequence message = {Class#contract[_NAME_], Class#contract[_REQUIREMENTS_]} -- crash_message("Contract %s not satisfied!\nRequirements: %s", message) --] contract create atom class_pointer: -1 <= return >= 0 export procedure create() return class_pointer docline "-1 means error, >= 0 means 'This is my pointer and I love you so much!'" end contract --[ About @ --- @ could be a routine name and will be (auto-) called if its Requirements are not satisfied --- I think for ClassError it must be a procedure. --- And the format (fmt) of ##error:crash_message(sequence fmt)## is optional to use --- example: --- fmt could be by default: sprintf("%s is neither %d nor %d", {...}) --- fmt by user would be used like any ##sprintf## i.e. @ClassError("...", {...}) --- See: [["About A Contract"]] --] contract destroy integer code return >= 1 @ClassError -- should it be @ClassError() ?? or return <= 0 @ClassError --- export function destroy() return code docline "<= 0 means no error and >= 1 means an error" end contract --- More (explicit) contracts if needed ... --[ About 'magic routines' -- It's magic if no function was defined -- Like in other languages (Java, etc.) --] export function equal() return boolean export function hash() return sequence export function serialize() return sequence export procedure deserialize() [...] end interface --] interface Animal: Class -- ": Class" is optional, any class/interface/contract/etc. will be inherited from Class contract name sequence name = "Animal" end contract -- Return name of Animal contract export function get_name(): string return name: sequence end contract --- override in an interface is a 'silent' contract: this must be overridden! override function equal() -- should a type-hint be required ?? override function hash() --- end interface class Cow: Animal sequence name = "Cow" export function get_name(): string return name end function export function equal(@Class seq) return equal(seq#name, name) end function export function hash() return name end function end class class Goat: Cow override sequence name = "Goat" [...] end class
Goat#get_name()
class_pointer goat_ = getclass("Goat") -- or get_class("Goat") -- is case-insensitive method_return goat_name = getmethod(goat_, "get_name", {}) -- same here
class_pointer is an atom
method_return is a sequence; {atom class_pointer, sequence method_name, object return_value}
class_pointer goat_ = class:new("Goat") method_return goat_name = class:method(goat_, "get_name", {}) -- or class:call(...) -- or class:func(..) / class:proc(...)
It could be implemented step by step.
The point is to use interfaces and contracts.
Better documentation to read by an IDE/Editor and any human.
The first step could be to ignore 'interface ... end interface'.
It's than a stub. Used for documentation, only.
--[ About "doc...end doc" and "docline" --- I think it's good practice to say which comment is more than a hint for the code owner. --]
Forked into: [OE] Suggestion for OpenEuphoria 'Next' | Class/Interface/Contract
5. Class/Interface/Contract -- Re: fake class in OE
- Posted by petelomax Feb 23, 2021
- 1309 views
class_pointer goat_ = class:new("Goat") method_return goat_name = class:method(goat_, "get_name", {}) -- or class:call(...) -- or class:func(..) / class:proc(...)
Erm, this currently/already works in Phix
class Goat string name function get_name() return name end function end class Goat goat = new({"Gertrude"}) ?goat.get_name()
Note that goat.name works the same as goat.get_name() here, because it recognises the "get_" part.
6. Class/Interface/Contract -- Re: fake class in OE
- Posted by irv Feb 23, 2021
- 1323 views
- Last edited Feb 25, 2021
To expand on that (Pete will correct me if I'm wrong):
With Phix, a class can have public, or private, properties.
When you declare a property as public, it acts just like any other variable, except that it is "owned" by the class instance. Types work the same as they do elsewhere, but with an added feature (we get to that later).
class Cow public integer horns; end class Cow bossie = new() ? bossie -- {"struct","Cow",4,1} instance 1 of class Cow Cow bessie = new() ? bessie -- {"struct","Cow",4,2} instance 2 of class Cow bessie.horns = 2 bossie.horns = 0 ? bessie.horns -- prints 2
If you declare a property as private, Phix looks for a routine of the same name, prepended by "set_" or "get_".
class Cow private integer horns; procedure set_horns(integer n) -- we have a chance to do something in addition to just setting the number of horns if n < 0 or n > 2 then ?"You're kidding, right?" -- made up example; else this.horns = n end if end procedure function get_horns() -- maybe do something here (beep once for each horn?) return this.horns end function end class ? bossie.horns -- automatically calls function get_horns() for the bossie instance bessie.horns = 3 -- automatically calls procedure set_horns() for the bessie instance
Properties aren't limited to the normal types (integer, bool, atom, string, sequence, or user-written types), they can also be declared as being a class type. For example, think of a Dialog window, which pops up a message.
It will have, at the least, a label with some text, a button or two, and perhaps an Icon: So you will have written a Button class, an Image class, and a Label class. Then the Dialog might have either public or private properties of those types:
include Image.e -- exports declaration and code for class Image; class Dialog private Image icon; procedure set_icon(Image i) -- will only accept an instance of Image class; ? i -- {"struct","Image",6,1} <-- this is the instance passed to set_icon() -- do something with that image (resize it, perhaps?) this.icon = i -- then update the dialog's icon, probably by calling a c_proc() In GTK, it would look something like: c_proc(define_c_proc(GTK,"gtk_dialog_set_image",{C_POINTER,C_POINTER}),{this.handle,i.handle}) end procedure end class Dialog d = new() Image x = new({"mongoose.jpg"}) d.icon = x -- calls the set_icon() function for class Dialog ,instance d, passing the Image structure;
Of course, a Dialog is a kind of Window, so they share some of the same properties, for example, size. Rather than write and debug a set_size() function for every object that has a size property, it's better to do that just once:
include Window.e -- exports declaration and code for class Window -- the Window class declares a private sequence size; include Image.e class Dialog extends Window -- inherit properties and code from Window (can inherit from more than one class) private Image icon; procedure set_icon(Image i) this.icon = i -- update the dialog's icon end procedure end class Dialog d = new() d.size = {300,400} -- calls the set_size() function in the Window class Image x = new({"mongoose.jpg"}) d.icon = x
Now, anything that derives from a Window automatically has the ability to set or get its size.
7. Alternative: Module -- Re: fake class in OE
- Posted by mitgedanken Feb 24, 2021
- 1243 views
- Last edited Apr 25, 2021
8. Alternative: Module -- Re: fake class in OE
- Posted by katsmeow Feb 24, 2021
- 1193 views
Responding to mitgedanken ...
The problem with export function get_horns() is the same problem with most computer languages, and some people: it's fixed, the system is fixed, you cannot add a get_ anything else while the program is running, or any sort of parameter which you may discover next week. With this way of doing things, the programmer must know in advance all the possible things that could be setted or getted, and write code for it, which if you think about all the things in the world you know parameters about, is going to make for a terribly bloated application.
Responding to Icy_Viking ...
I hoped i was saying this could be written in OE and added soon as you are done, because i suggested it as an include file. There's no developers working on OE, there won't be any new releases (hasn't "release often" turned into 10 years now?). Phix seems to have a class that's as good as any language's. As i cannot write a real class for OE, i thought of a fake class. A beauty of it being OE source code is you can tweak it to suit your needs. For instance, use an external database for the parameters of each item and class, such as SQL?
Kat
9. Re: Responding to mitgedanken -- Re: fake class in OE
- Posted by mitgedanken Feb 25, 2021
- 1182 views
Responding to mitgedanken ...
The problem with export function get_horns() is the same problem with most computer languages, and some people: it's fixed, the system is fixed, you cannot add a get_ anything else while the program is running, or any sort of parameter which you may discover next week. With this way of doing things, the programmer must know in advance all the possible things that could be setted or getted, and write code for it, which if you think about all the things in the world you know parameters about, is going to make for a terribly bloated application.
[...]
Kat
writable integer horns -- if it's writable it's readable too readonly sequence name
Or mutable immutable. Both examples only as a suggestion.
Edit
public integer horns export sequence name
But I'm not sure if this is a good idea.
end Edit
my_cow#name = "Polly" -- error/crash my_cow = Cow#name -- ok my_cow = Cow#get_var('name') -- ok -- set_var(..., ...) -- error/crash my_cow#horns = 1 -- ok my_cow#set_var('horns', 1) -- ok if my_cow#horns > 0 then -- ok ... end if
10. Alternative: Module -- Re: fake class in OE
- Posted by Icy_Viking Feb 25, 2021
- 1183 views
Responding to mitgedanken ...
The problem with export function get_horns() is the same problem with most computer languages, and some people: it's fixed, the system is fixed, you cannot add a get_ anything else while the program is running, or any sort of parameter which you may discover next week. With this way of doing things, the programmer must know in advance all the possible things that could be setted or getted, and write code for it, which if you think about all the things in the world you know parameters about, is going to make for a terribly bloated application.
Responding to Icy_Viking ...
I hoped i was saying this could be written in OE and added soon as you are done, because i suggested it as an include file. There's no developers working on OE, there won't be any new releases (hasn't "release often" turned into 10 years now?). Phix seems to have a class that's as good as any language's. As i cannot write a real class for OE, i thought of a fake class. A beauty of it being OE source code is you can tweak it to suit your needs. For instance, use an external database for the parameters of each item and class, such as SQL?
Kat
Well yes a fake class is a good idea. True Phix does have a struct/class support. Also, yeah its been years since OE has had an official release.
11. Alternative: Module -- Re: fake class in OE
- Posted by irv Feb 25, 2021
- 1187 views
Responding to mitgedanken ...
The problem with export function get_horns() is the same problem with most computer languages, and some people: it's fixed, the system is fixed, you cannot add a get_ anything else while the program is running, or any sort of parameter which you may discover next week. With this way of doing things, the programmer must know in advance all the possible things that could be setted or getted, and write code for it, which if you think about all the things in the world you know parameters about, is going to make for a terribly bloated application.
... Kat
That's correct. There may be a way to avoid that problem, however,if the base class has 3 routines: add_property(), set_property(), and get_property(), along with a dictionary or db to store the name/value pairs (and perhaps a function to be called to override the one declared in the base class?).
12. Re: fake class in OE
- Posted by mitgedanken Feb 25, 2021
- 1159 views
Only a hint
But for now there is no way to get the namespace programmatically.
A constant must be set instead.
13. Alternative: Module -- Re: fake class in OE
- Posted by katsmeow Feb 25, 2021
- 1148 views
Responding to mitgedanken ...
The problem with export function get_horns() is the same problem with most computer languages, and some people: it's fixed, the system is fixed, you cannot add a get_ anything else while the program is running, or any sort of parameter which you may discover next week. With this way of doing things, the programmer must know in advance all the possible things that could be setted or getted, and write code for it, which if you think about all the things in the world you know parameters about, is going to make for a terribly bloated application.
... Kat
That's correct. There may be a way to avoid that problem, however,if the base class has 3 routines: add_property(), set_property(), and get_property(), along with a dictionary or db to store the name/value pairs (and perhaps a function to be called to override the one declared in the base class?).
I had imagined add_ would be part of set_, but yes, having them be separate makes it easier to apply different rules and error checking to each. It's also more possible (as in, without breaking anything) for a new feature that cannot be properly described yet. You must be thinking of the platypus problem?
There's other database management tasks unrelated to the class which would need tending to. I had imagined a OE layer to deal with the class work, and interface to your choice of database behind, because once the db is working, it becomes just a "black box" you no longer think about. Simple small stuff may be dealing with only (only?) a game (class = "habitat") and be stored in nested sequences, but for real dealing with taxonomy of animals may need a semi-pro database first thing (and occasionally forking the db into subclasses). Etc. I suggest working on the class stuff first, and use sequences to store the data (even then.. split(), store(), load(), etc).
Kat
14. Re: fake class in OE
- Posted by katsmeow Feb 25, 2021
- 1142 views
Only a hint
Please, continue.
A constant must be set instead.
I hope i understand your meaning and i do not wander outside scope...
Ah, but there is if you use a preprocessor that re-writes the code. I made "varname" and varname access the same data for small amounts of shared_vars by simply using a case stack. And to know the name of the variable in OE's type system, you need only comment out the programmer's declaration, and insert your own unique type, which only that varname is type-checked with, ergo in that type-check code, it can be only one varname.
On startup, all the known data can be loaded as strings (vs enumerations in code?), and a case stack can equate "varname" and varname if necessary. Sure it can be done differently if OE/Phix had a variable_id().
Kat
15. Re: fake class in OE
- Posted by ghaberek (admin) Feb 25, 2021
- 1133 views
Please, continue.
Yes, as of I think 4.0 (maybe it was 4.1) you can call routine_id() with a namespace:
include std/map.e include std/socket.e as sock ? routine_id( "map:new" ) -- default namespace ? routine_id( "sock:create" ) -- custom namespace
-Greg
16. Re: fake class in OE
- Posted by mitgedanken Feb 26, 2021
- 1115 views
[...]
include std/map.e include std/socket.e as sock ? routine_id( "map:new" ) -- default namespace ? routine_id( "sock:create" ) -- custom namespace
-Greg
Yes, that's what I mean.
Then, you can use a constant to concat
constant ns = "sock:" sequence from_somewhere = "create" routine_id(ns & from_somewhere) -- equal to "sock:create"
This is how I implement 'dynamic' plain OE modules.
17. Re: fake class in OE
- Posted by mitgedanken Feb 26, 2021
- 1115 views
Only a hint
Pass By Reference OOP Style
18. Re: fake class in OE
- Posted by petelomax Feb 26, 2021
- 1093 views
Only a hint, too
class Dude public: string fname, lname atom age procedure introduce() printf(1,"Hi I'm %s %s and I use Phix!\n", {fname, lname}) end procedure end class Dude my_dude = new({"John", "Smith", 32}) Dude cool_dude = new({"Ronald", "Weidner", 745}) my_dude.age = 22 printf(1,"%s %s is %d\n",{my_dude.fname,my_dude.lname,my_dude.age}) cool_dude.introduce() {} = wait_key()