View Issue Details

IDProjectCategoryView StatusLast Update
0000213LDMud 3.5LPC Compiler/Preprocessorpublic2011-02-14 00:22
ReporterlarsAssigned Tozesstra  
PrioritynormalSeverityfeatureReproducibilityN/A
Status closedResolutionwon't fix 
Summary0000213: Disallow callothers on Arrays [was: Special -> notation for array call-others]
Description[was: Special -> notation for array call-others]

Date: Thu, 6 Jan 2000 10:16:35 -0500 (EST)
From: fiona
Short: Special -> for array calls
Type: Feature
State: New


>From Fiona: invent a second -> just for arr->fun() calls, and add
a pragma or cmdline option to make it mandatory for this type of call.
Other wise something like m[i][j][k]->fun() may fall badly over a
missing index.
TagsNo tags attached.

Relationships

child of 0000663 resolvedzesstra RfC: Remove some configuration switches in 3.5.x 

Activities

zesstra

2009-10-06 04:42

administrator   ~0001493

This would accomodate people like Fuchur who don't like the call_other on arrays for exaxtly this reason.
Or we may abandon the operator completely in this case and only allow either call_other(arr,...) or call_array(arr,...), but I am not sure if I like that.

zesstra

2009-11-17 13:39

administrator   ~0001627

I had a discussion about the array calls with a fellow wizard. Finally he asked me if arr->fun() will not work anymore in the future...
Currently, I have no good answer to this. So, I think, we should discuss this issue soon and decide what to do. If we change the syntax, it should be done sone, before too many people use it.

Please add you opinions.

Sorcerer

2009-11-18 02:52

updater   ~0001628

Last edited: 2009-11-18 02:54

I think it is too late to avoid breaking a significant amount of code by disallowing arr->fun(), since I am encountering it on a regular basis in mudlibs.

Nevertheless I agree with fufu's comment in the parent issue, that with map_objects() there is an efun available that does exactly what people do by arr->fun() now (even including the tolerance for 0 entires).

So I see no reason to add a new efun (call_array()) that would do the same as map_objects() (please correct me, if I overlooked something).
I have no real preference on keeping or disallowing arr->fun(), but if you disallow arr->fun(), it would be only consistent to also disallow call_other(arr, fun) in order to keep the equivalence of x->fun() and call_other(x, fun). In that case, we simply have call_other() for single objects and map_objects() for arrays of the same.

Gnomi

2009-11-18 03:08

manager   ~0001629

I don't think that's too late. Mudlibs can always overload call_other with a simul-efun to keep the array call behavior. But then we might as well keep the USE_ARRAY_CALLS configuration switch. I'm undecided here.

invisible

2009-11-18 13:57

reporter   ~0001630

A question about "Mudlibs can always overload call_other with a simul-efun to keep the array call behavior.": is -> always and under any circumstances simply replaced with call_other by the compiler? In this case it really shouldn't matter to much.
Personally I'd prefer the USE_ARRAY_CALLS switch (it could simply default to 'no') since we use (object*)->fun() a lot in RoleMUD and I think walking through the array and checking for 0 or non-object entries would be slower when implemented as simul-efun.

Gnomi

2009-11-18 14:08

manager   ~0001631

If there is an simul-efun with the name 'call_other' then -> will be compiled as a call to this simul-efun.And this simul-efun doesn't have to walk through the array, but can call map_objects() instead.

zesstra

2009-11-18 14:26

administrator   ~0001632

I am also undecided. I don't really like to keep USE_ARRAY_CALLS forever, because it fragments the LPC language.
I used the -> on arrays occasionally, but I don't insist on it and would probably just use map_objects() and don't add the call_other sefun.

bubbs

2009-11-18 14:52

reporter   ~0001633

What's the argument against array->func(), again? To me it seems a great addition to the language.

I'd like to see it retained, and it people don't like USE_ARRAY_CALLS, maybe replace it with a pragma?

sinnvoll

2009-11-19 12:20

reporter   ~0001634

The way I unstand it:
example an 3 dimonsional array, an array of an array of an array

a[x][y][z]->fun(); //valid call, call function on an element
a[x][y]->fun(); //valid call, calls for a whole row of element
                   // would throw an error,
                   // if call_other was not valid for arrays
                   // it should be an error, if an index [z] is missing

This can be resolved, using:
({a[x][y]})->fun(); // throws an error
It seems ({o})->fun(); is only valid for o from type object

Maybe there should be an efun deep_call_other.

_xtian_

2009-11-20 06:03

reporter   ~0001635

If you decide to disable this feature, I would prefer a way (warning?) to catch these calls at compile-time than having to overload the sefun.

invisible

2009-11-20 07:52

reporter   ~0001639

The sefun could easily print a warning, couldn't it?

ff_dafire

2009-11-20 18:32

reporter   ~0001640

I like the array calls..

Enabling it for everyone breakes nothing... removing it might break existing code.

Of course it's possible to create a sefun to get everything running again... but it would also be possible to create a sefun that disallows the array calls in muds where it's frowned upon :)

Sorcerer

2009-11-21 06:26

updater   ~0001641

Ponderig some more on this, there should be definitely a change be made here:
call_other(arr,fun,extra) is identical in function to map_objects(arr,fun,extra) as far as I can see (including the undocumented feature of map_objects to accept the names ob objects - see issue 706).

By now, my preference is on deprecating map_objects() (unless I overlooked something that cannot be done by call_other()) and making USE_ARRAY_CALLS permanent. I think, for a multi-dimensional array it should be up to the programmer to make sure to call (any function) with the proper set of indices. Furthermore that would eliminate an efun which I consider an additional boon.

Coogan

2009-11-22 06:03

reporter   ~0001642

I believe you don't see the aspect of map_objects() which REPLACES the particular objects in the returned array.

So, map_objects() does not only do the same job as call_other(array,fun) but more stuff. Therefore I don't see any reason to let call_other() take part in map_objects()'s job. Thinking further (with my limited viewpoint of not knowing the driver sources), array->fun() could internally be implemented as a call to map_objects() omitting the returned array.

My current preference is not allowing USE_ARRAY_CALLS. If a lib wants to allow that, it can offer an sefun::call_other(), replacing array-calls by calling map_objects().

Another question: is call_other(array, fun, extra) able to call extra-args by reference?
The reason behind that: Of course one could obsolete map_objects() and filter_objects() by using map() and filter() instead. [map_objects() --> map() and NOT map_objects() --> call_other()!!] But as far as I can see in the manpages, map() and filter() do not allow extra-args called by reference, and map_objects() resp. filter_objects() do not seem to have a problem with that.

Summarizing:
When calling-by-reference is ensured, map_objects() does the same like call_other(array, fun, extra) and map(array, fun, extra). If one wants to obsolete map_objects() (and consequently filter_objects(), too) the replacement should go towards map() and filter(). In these cases it's not needed to have an additional call_other(array, fun), so removing USE_ARRAY_CALLS would only be straight-forward.

Coogan

2009-11-22 06:11

reporter   ~0001643

A correction to myself: map_objects() could only be replaced by map() if map() would accept sth. like
  map(array, string func, mixed extra)
-- the same applies to filter().

invisible

2009-11-22 08:11

reporter   ~0001644

I think we're now going a bit too far. map() and map_objects() do different things (map can calls a function of *one* object for each item in the array, whereas map_objects calls a function in *each* item). Thus call_other(array, fun, extra) and map(array, fun, extra) behave quite differently. Merging these functionalities could easily lead to confusion.

map_objects() could of course be replaced by something like map( object*, #'call_other, "function" ) though.

fufu

2009-11-23 06:06

manager   ~0001646

I still stand by my opinion from 0000663; it's impossible to distinguish a call_other to an object from an array call_other at a glance, but it makes a significant difference operationally.

Also, while it's true that this won't break most code, there is also a cost associated with making bad code fail silently or exhibit strange behaviour rather than getting a clear runtime error.

I believe these are good reasons for disabling array call_others.

Removing the feature completely doesn't seem to be a viable option either - the first point above means that finding and replacing all occurences of array call_others is hard manual work, and would be a significant burden for muds using array calls now.

So personally I think keeping the USE_ARRAY_CALLS flag is the best option. It also has limited effect on the driver code, so maintaining is rather cheap.

Sorcerer

2009-11-23 06:26

updater   ~0001647

Last edited: 2009-11-23 06:26

Just a quick comment to Coogans note:
call_other() does replace the the particular objects in the returned array:
ret=call_other(arr,fun) and ret=map_objects(arr,fun) will return the same ret.
If you meant another thing, please correct me.

Coogan

2010-03-03 17:47

reporter   ~0001747

Any news here?
For the records, I still fully agree with Sorcerer (note 0001628) and fufu (note 0001226 in the parent issue).

zesstra

2010-03-03 18:27

administrator   ~0001751

Not really. :-/ I glanced over the opinions and counted. So far:
In Favor of -> on Arrays: 3
Against -> on Arrays: 2
Undecided: 3

zesstra

2010-03-03 18:31

administrator   ~0001752

I updated the issue title, because it seems the discussion is quite consentious about not introducing a special notation/efun for callothers on arrays, but about disabling callothers on arrays altogether...
Will additionally move it to 3.5.

Gnomi

2010-03-03 18:52

manager   ~0001755

I'm not undecided anymore. :-)

I'm in favor of array calls. In the past a lot of efuns have been merged to allow a more concise syntax (map_array, map_mapping -> map, m_sizeof, strlen -> sizeof) and I like that direction. And I would like to see the same happening to call_other / map_objects. I can even imagine allowing call_other on mappings, structs or closures. And in a future there might be lightweight objects of which call_other could take care of, too.

So I see call_other as a multi-purpose weapon, not just one highly specialized for single objects.

I see Fuchur's point, that a more generic function introduces possibilities for subtle errors. But I've never encountered such an error in production code, yet. And I think the runtime type checks do a better job in preventing these things than restricting efuns or operators.

zesstra

2010-03-04 03:59

administrator   ~0001756

I basically agree with respect to the runtime type checks. Although there is a shortcoming: arrays don't really have a type describing their contents (e.g. int *arr could actually be an array of objects and currently there is no way how RTT checks could prevent it).
Because call_other accepts arrays, objects, strings (and 0 of course), there is some room for errors which can't be detected by the compiler+interpreter. Nevertheless I also believe, such errors would be caught during code testing.
So my main concern is Fuchurs point about readability. The more the meaning of an instruction depends on its context, the more difficult it is for any reader/evaluator.
Concerning a possible extension of -> for even more types: IMHO it makes sense for calling functions in light-weight objects, because it is basically the same operation. (This holds true for array calls as well.) For the rest, I am undecided again, because there is a bigger difference to the classical meaning of ->. But that is a future issue.

_xtian_

2010-03-04 10:14

reporter   ~0001757

In my opinion it should stay: Mainly, because it has been established for too long (our mudlibs would have to be adapted --> work, which I am not looking forward to) and the votes are not clear enough, which means that the reasons for changig it are not that compellent.

Also: In the past, when ldmud changed or deprecated efuns, the culprits were more or less easily identifiable by using grep. In this case things would not be that easy.

So either we risk code not loading or not running in our production systems by design (not good) or we force mudlibs to overwrite the sefun, what again fragments the language (not good).

Bardioc

2010-03-05 14:13

reporter   ~0001766

I vote for this to stay too, cause it IS indeed very convenient!

zesstra

2010-03-14 11:25

administrator   ~0001796

My vote is a lukewarm 'keep it'. But even without it, the opinion here cleared up in the meantime... So, I guess, we should close this.

What remains to decide it the question of array call-others being optional. Probably good to use a different issue for that.

zesstra

2011-02-14 00:22

administrator   ~0001970

Since there is a majority for keeping the call-other on arrays and we don't want to cause more work for users as necessary: closing this as WONTFIX (i.e. we keep -> on arrays).

For the discussion about the configuration switch USE_ARRAY_CALLS I created 0000774.

Issue History

Date Modified Username Field Change
2004-11-26 23:06 lars New Issue
2009-10-06 04:42 zesstra Note Added: 0001493
2009-11-17 13:36 zesstra Relationship added child of 0000663
2009-11-17 13:39 zesstra Note Added: 0001627
2009-11-17 13:39 zesstra Status new => feedback
2009-11-18 02:52 Sorcerer Note Added: 0001628
2009-11-18 02:52 Sorcerer Note Edited: 0001628
2009-11-18 02:54 Sorcerer Note Edited: 0001628
2009-11-18 03:08 Gnomi Note Added: 0001629
2009-11-18 13:57 invisible Note Added: 0001630
2009-11-18 14:08 Gnomi Note Added: 0001631
2009-11-18 14:26 zesstra Note Added: 0001632
2009-11-18 14:52 bubbs Note Added: 0001633
2009-11-19 12:20 sinnvoll Note Added: 0001634
2009-11-20 06:03 _xtian_ Note Added: 0001635
2009-11-20 07:52 invisible Note Added: 0001639
2009-11-20 18:32 ff_dafire Note Added: 0001640
2009-11-21 06:26 Sorcerer Note Added: 0001641
2009-11-22 06:03 Coogan Note Added: 0001642
2009-11-22 06:11 Coogan Note Added: 0001643
2009-11-22 08:11 invisible Note Added: 0001644
2009-11-23 06:06 fufu Note Added: 0001646
2009-11-23 06:26 Sorcerer Note Added: 0001647
2009-11-23 06:26 Sorcerer Note Edited: 0001647
2010-03-03 17:47 Coogan Note Added: 0001747
2010-03-03 18:27 zesstra Note Added: 0001751
2010-03-03 18:31 zesstra Note Added: 0001752
2010-03-03 18:31 zesstra Summary Special -> notation for array call-others => Disallow callothers on Arrays [was: Special -> notation for array call-others]
2010-03-03 18:31 zesstra Description Updated
2010-03-03 18:31 zesstra Project LDMud => LDMud 3.5
2010-03-03 18:52 Gnomi Note Added: 0001755
2010-03-04 03:59 zesstra Note Added: 0001756
2010-03-04 10:14 _xtian_ Note Added: 0001757
2010-03-05 14:13 Bardioc Note Added: 0001766
2010-03-14 11:25 zesstra Note Added: 0001796
2011-02-14 00:22 zesstra Note Added: 0001970
2011-02-14 00:22 zesstra Status feedback => closed
2011-02-14 00:22 zesstra Assigned To => zesstra
2011-02-14 00:22 zesstra Resolution open => won't fix