On 11 September 2010 04:41, Mike Caron <[email protected]> wrote: > On 9/10/2010 12:26 PM, Ralph Versteegen wrote: >> >> On 11 September 2010 03:15, Mike Caron<[email protected]> wrote: >>> >>> On 9/10/2010 10:58 AM, Ralph Versteegen wrote: >>>> >>>> On 10 September 2010 03:18, James Paige<[email protected]> >>>> wrote: >>>>> >>>>> On Thu, Sep 09, 2010 at 10:18:41PM +1200, Ralph Versteegen wrote: >>>>>> >>>>>> Well, this email was originally going to be part of the one about SAV, >>>>>> but then I remembered that NPC instance data has never been read from >>>>>> .SAV! >>>>>> >>>>>> I'd like start adding of data to NPC instances, like zone >>>>>> restrictions. (I'll have to create an NPC instance editor.) >>>>>> Actually, I already started. A few months ago I wrote these (below), >>>>>> but didn't check them in because I was waiting for .SAV to be dropped. >>>>>> Opps! Sorry Jeremy! >>>>>> But anyway, I just thought I may as well ask about functions for >>>>>> reading/writing NPC instance data. >>>>>> >>>>>> functions: >>>>>> 472,setnpcbit,3,0,0,1 #set NPC instance bit (npcref, bit, >>>>>> value) >>>>>> 473,getnpcbit,2,0,0 #get NPC instance bit (npcref, bit) >>>>>> >>>>>> constants: >>>>>> 0,NPCbit:ignore walls >>>>>> 1,NPCbit:not obstruction >>>>>> 2,NPCbit:suspend use >>>>>> 3,NPCbit:suspend movement >>>>>> >>>>>> (Incidentally, those "bits" are not actually stored as bits in the >>>>>> UDT.) And then other non-flag data like zone restrictions would each >>>>>> get a pair of getter/setting functions. Would people prefer something >>>>>> more uniform like alter/read npc (below)? Or the opposite extreme of >>>>>> individual read/write functions for each bit? >>>>>> >>>>>> 472,read npc instance,3,0,0,1 #set NPC instance data (npcref, >>>>>> data id, value) >>>>>> 473,write npc instance,2,0,0 #get NPC instance data (npcref, >>>>>> data id) >>>>>> >>>>>> 0,NPCinst:ignore walls >>>>>> 1,NPCinst:not obstruction >>>>>> 2,NPCinst:suspend use >>>>>> 3,NPCinst:suspend movement >>>>>> 4,NPCinst:zone >>>>> >>>>> I like individual functions for each bit. I may have advocated generic >>>>> functions with constants in the past, but I am really starting to hate >>>>> the heck out of them. it is all about what I want to be writing as an >>>>> end-user in my script: >>>>> >>>>> # this is good >>>>> set npc ignore walls(npc, true) >>>>> >>>>> # this is bad >>>>> set npc bit(npc, NPCbit:ignore walls, true) >>>> >>>> Well, I choose the second approach because I hate having too many >>>> functions (and having to document them :) ), because it makes the >>>> dictionary extremely verbose: consulting a compact table as for >>>> alternpc is much faster (I actually prefer read/alternpc to trying to >>>> remember over 100 menu functions, for example). And our commands are >>>> inconsistent and difficult to remember as a rule -- I can never >>>> remember whether to use "slice parent" or "parent slice" -- so I end >>>> up looking up an awful lot. However a few paragraphs of documentation >>>> for every tiny bit is much more fair for people who aren't familiar >>>> with engine internals in the first place. >>>> >>>> However despite all that, I must agree with you: I didn't realise how >>>> overly verbose the setnpcbit approach was. >>>> >>>> But while we're on the topic of too many functions which are >>>> impossible to remember, I think I'll sidetrack into adding structures >>>> to HS, which I've been meaning to talk about. Having actually used >>>> Euphoria a whole a couple months back, I take back what I said about >>>> it being a nice language. I think not supporting user defined data >>>> structures in the new HamsterSpeak is out of the question, it's just >>>> unworkable. >>>> >>>> And following this train of reasoning, if we have user defined >>>> structures, and function objects, then we may as well add some form of >>>> object orientation, since you're already nearly there. >>>> >>>> And if we now present a slice handle, npc reference, menu handle or >>>> whatever else as an object with members and/or methods, we can provide >>>> an alternative way to interact these objects that's less verbose, >>>> highly consistent, easy to remember and compactly documentable: >>>> menuitem.caption >>>> instead of >>>> get menu item caption (menuitem) >>>> >>>> heroes[who].stats[stat.hp] += x >>>> instead of >>>> set hero stat(who, stat:hp, get hero stat(who, stat:hp) + x) >>>> and so on. >>>> >>>> The exact details don't matter right now, but this is very similar to >>>> the Magic Variables plan. >>> >>> I'm having deja vu; this is a lot like the transition between the >>> mathematical operators being functions and them being actual symbols. >>> (although, this transition occurred long before I had ever used the OHR) >>> >>> Hypothetically speaking, how would you implement these structs? Would you >>> go >>> for a classical model (like how they work in C), or something else? >> >> I was thinking something along the lines of Python or Lua, which >> implement objects in very similar ways. I'm not all that familiar with >> Lua though. >> >> We can afford to be less flexible than these though. For example, >> should you be able to add new members to builtin data types, like >> setting npcref.is_hallucinating := true? (Realise that if we do this, >> it would be handled entirely by the script interpreter, and in fact I >> think it's quite likely we can add builtin types without having to >> significantly modify any existing commands beyond what's needed for >> dynamic types anyway) I think it looks elegant, but isn't there a rule >> of thumb that composition is preferred to inheritance? > > It depends on the situation. It boils down to has-a vs is-a, really. Or, on > other words, if it looks like a duck, quacks like a duck, and has a feathers > property, but was created by CreateChimera(), can we still treat it as a > duck? > > (Lua, Python and Javascript say yes. C/++, FreeBasic and others say no)
I'm inclined to say yes. I'm just looking for ways to make optimisations easy to do. I want to do something like V8's "hidden class" optimisation, but without too much hassle. One approach would be to forbid adding new methods to objects at any time (ie. actually requiring class declarations). >>> If you're looking for suggestions, I think Lua has the best system. >>> Basically, every variable that isn't a basic type (integer, string, etc) >>> is >>> a table (i.e., a set of key->value pairs). If the indicies are numeric, >>> you >>> call it an array, whereas if the keys are strings, you call it a hash. If >>> the values are functions, then it must be an object. >>> >>> Even better, you can set what's called a "metatable", which defines >>> functions that are called when the table is operated on, which allows you >>> to >>> simulate properties. The identity of an object is based on its metatable. >>> If >>> get_metatable(objA) == get_metatable(objB), then they must be instances >>> of >>> the same class. >> >> I'm hazy on this part of lua, but I think we should make properties as >> easy as possible to write. In fact, they're actually the focus of this >> suggestion, rather than methods in general. > > Just to clarify, a field is a data member on an object. eg, myobj.color. A > property is actually a method that disguises itself as a field, but can be > read only, or have special validation done, or maybe the property doesn't > even have a backing store, but is actually inferred from other things. > > In light of this, Lua uses the metatable to distinguish whether it's > assigning a field, or calling a method when you do this: Unless I'm looking at outdated information, this is done by setting __index and __newindex metamethods. Far from built-in or simple. Doesn't look very efficient either. > myobj.color = "red"; > > If color is a property, then it will call the appropriate function with the > value "red". If it's a field, then it will store "red" under "color". > > (You already know this. I don't know why I felt it necessary to write all > the above.) > >>> One of Lua's interesting quirks is that it actually has two ways to >>> invoke >>> methods on objects. If you use the dot operator (myobj.method()), it's >>> called normally (eg, just as method()). But, if you use the colon >>> operator >>> (myobj.method()), it's called by passing the table as the first operator >>> (eg, method(myobj)). >> >> This scared me a little, but I guess it's good to be explicit about >> whether you're calling a method or a function object member with >> method-like syntax. I doubt that adding more syntax than necessary to >> HS is a good idea, though. > > I don't necessarily like it either, but it's an artifact of the way Lua > works. Lua doesn't have a magic "this" parameter. A function has to expect > it as an explicit parameter. If the function doesn't expect it, then you > call it with the dot, and it doesn't get it. If it *does* expect it, call > with the color, and it will. > > Of course, if you DO use the magic "this", then it's a non-issue. magic "this"? Do you mean the automatic hidden "self" if you declare a method using colon syntax? >> A whimsical thought: it occurred to me that using : instead of . would >> be more idiomatic for HS. > > Just a minor problem: All 12 hojillion constants that already use : > >>>>> As I said, I know the library is already full of stuff that does it the >>>>> second way, I just wish now that it wasn't. >>>>> >>>>> But I suppose this is a matter of personal taste, and my opinion on >>>>> this >>>>> is certainly not the final word. >>>>> >>>>> --- >>>>> James >>>>> _______________________________________________ >>>>> Ohrrpgce mailing list >>>>> [email protected] >>>>> http://lists.motherhamster.org/listinfo.cgi/ohrrpgce-motherhamster.org >>>>> >>>> _______________________________________________ >>>> Ohrrpgce mailing list >>>> [email protected] >>>> http://lists.motherhamster.org/listinfo.cgi/ohrrpgce-motherhamster.org >>> >>> _______________________________________________ >>> Ohrrpgce mailing list >>> [email protected] >>> http://lists.motherhamster.org/listinfo.cgi/ohrrpgce-motherhamster.org >>> >> _______________________________________________ >> Ohrrpgce mailing list >> [email protected] >> http://lists.motherhamster.org/listinfo.cgi/ohrrpgce-motherhamster.org > > _______________________________________________ > Ohrrpgce mailing list > [email protected] > http://lists.motherhamster.org/listinfo.cgi/ohrrpgce-motherhamster.org > _______________________________________________ Ohrrpgce mailing list [email protected] http://lists.motherhamster.org/listinfo.cgi/ohrrpgce-motherhamster.org
