mIRC Homepage
Posted By: Raccoon Backward compatible + User friendly %arrays. - 31/03/10 10:58 PM
I wish to suggest a simpler method to allowing dynamic variables, or variable arrays, in addition to the current methods.

inc %FLOOD.TEXT. [ $+ [ $cid ] $+ . $+ [ $chan ] $+ . $+ [ $nick ] ]
if ($($+(%,FLOOD.TEXT.,$cid,.,$chan,.,$nick),2) >= 10) { do stuff }

inc %FLOOD.TEXT[$cid][$chan][$nick]
if (%FLOOD.TEXT[$cid][$chan][$nick] >= 10 { do stuff }

By forcing evaluation of the contents of []'s within variable names, mIRC should be able to create dynamic variables, including the '[' and ']', that are easier to read and manipulate.

I understand the scope of issues affecting the implementation, parsing, use, and backward compatibility of variable arrays. I believe this method should both minimize compatibility issues with existing scripts, while being extremely user-friendly and intuitive to all users.


/set %array[1] : creates a variable named %array[1], as already does.
/set %array[%i] : creates a variable named %array[1], evaluating the contents of [], %i.
/set %array[$me] : creates a variable named %array[Raccoon], evaluating the contents of [], $me.

I'm using %array as an example. This would apply to any variable containing a '[' and ']' in its name.

Only the contents of [...] is actually evaluated.
No spaces are required or permitted.
Multiple sets of [...] are evaluated.

/set %array[$me][$chan] : creates a variable named %array[Raccoon][#mIRC]
/set %array[$me]foo[$chan] : creates a variable named %array[Raccoon]foo[#mIRC]
/set %array[$me]$foo[$chan] : creates a variable named %array[Raccoon]$foo[#mIRC]

If the evaluated variable or identifier contains spaces, or variable-name prohibited characters, they are replaced by underscores "_".

/set %array[$me][$1-] : creates a variable named %array[Raccoon][Hello_world.]

Using the variables doesn't require any special evaluation with $eval() or the like.

/echo -a %array[$me][$chan] : should work as expected.
if (%array[$me][$chan] == $true) : should work as expected.

Parser Issues:

I understand that there are a multitude of parser / evaluation issues involved. I know that commands like /set and /var treat the first parameter (%variable) in a special way so as not to evaluate the variable but treat it as an explicit name.

Since mIRC already has special handling in place for recognizing and evaluating variables as appropriate, I simply suggest checking if the variable name contains [] and gives the contents of [] a round of personalized evaluation before naming the variable.

This should not affect existing scripts with variables containing [], since %variable[xyz] is still %variable[xyz]. This would only affect scripts that explicitly tried naming variables %variable[%foo] or %variable[$foo]. This type of naming convention is RARE and likely unseen in wide use today.

mIRC should continue to treat dynamic evaluation through use of %variable [ $+ [ $foo ] ] the same as it currently does. Since there are no touching [], this should be a simple matter.

Please give this suggestion some consideration so we can get on with simple dynamic variable arrays without the messy use of %xyzzy [ $+ [ $foo ] or $($+(%,xyzzy,$foo),2) which is painfully hard to read.

Thank you Khaled.

Eric aka Raccoon/EFnet
Other than readability, I see little reason for this. When setting a variable, you don't need to evaluate anything.

/set %array $+ $me value
^ would set %arrayRiamus2 to value

You only have to evaluate when reading the value. And it's not really all that hard to read $($+(%,array,$me),2) or %array [ $+ [ $me ] ] . Sure, it's easier your way for reading the variable, but I don't think it's worth all the effort of implementing it just to make it look "pretty."
I don't get it. What's the deal with people interjecting "work-arounds" when someone posts a feature suggestion? Does that mean the suggestion is no good?

Just because it can be done already, doesn't mean it can't be improved upon. Work-arounds are messy, hard to read, impossible to teach, and SLOW. Don't believe me? Read this article. http://www.xise.nl/mirc/wiki/doku.php?id=eval

Reading the most recent 10 threads in the feature suggestion forum, each of them state "yes, i know there's a work-around for this, but it's horribad", and yet people persist on replying with these unwanted hacks in some vein attempt to discredit the suggestion. Let Khaled be the judge.

Post count much?
At this point we might as well just ask for proper variable interpolation, because that's what this (almost) is. The only problem with your suggestion is that it's incomplete, because it only solves interpolation for a very stringent set of rules and for a variable name convention that just isn't used. What if people wanted to just do %var.%i.%chan?

Proper interpolation would get these and other benefits, ie.

//echo -a how many {$me}'s are there in the room?

And of course you could apply that same interpolation to the array syntax:

/set %array.{%i}.{#}.{$cid} 1
- or -
/set %array[{%i}][{#}][{$cid}] 1

This gives people the freedom to use any variable naming they want, and not only use this concept for "arrays". Interpolation would naturally solve evaluation as well, because it's implicit in the concept:

//echo -a %array[{%i}][{#}][$cid]

But of course this isn't *entirely* backwards compatible just like your suggestion isn't *entirely* backwards compatible, if you consider the edge cases:

/set %array[%i] <- currently sets "%array[%i]", so any scripts currently relying on such a variable name syntax would break. I'm sure it's rare, but it's probably just as rare as:

//echo -a How many {$me}'s are in the room?

And to clarify, the syntax for interpolation would be {...} where "..." must start with either $ or % (or # alone as a special case).
Two key points you raised.

1) The variable name convention I suggested "just isn't used" (in your words). This is the very reason I suggest it, because it wouldn't clash with naming conventions currently seen in mIRC scripts, and because it IS a standard naming convention seen in a plethora of other programming languages--even your own nickname--lending to general familiarity and appreciation.

2) "My suggestion isn't "entirely" backwards compatible." I never said it was. The only case it isn't backward compatible is, as stated above, if someone happened to use a "just isn't used" naming convention like "%array[%i]". But I'll take your word that it "just isn't used", which then should make my suggestion "entirely" backwards compatible.

I understand that a complete reworking of the parser using quoted text and evaluated expressions would clean things up nicely, but it's really not the issue I'm putting on the plate here.

I believe that the changes expressed in my suggestion would require a minimal amount of work to implement. Since variables are already placed and discovered by the parser, this suggestion only requires further pre-parsing of those variable names. Your method would require a much broader scope of script parsing, and would more-likely interfere with existing uses of (...) such as IF-conditions and identifier parameters.
My point is it would be as difficult (by the same token, as easy) to implement this for variable names only as it would be to implement this kind of interpolation everywhere. The only difference is that there would now be a new syntax to denote a variable,identifier or "#": {%var}, {$ident} and {#} respective. The boundaries in all cases would be simple to parse, so this would not be difficult to implement. All you'd do is add in the following logic in the current parser: "if char is '{' and next char is one of ($, % or #), evaluate contents until matching '}' in place". This same logic would be inside the parsing of variable names too, but that's insignificant thanks to the wonders of recursion. Note that this would be *as easy* as your logic for variable names only; in fact, it *is* the same logic: "if char is '[' and next char is ... evaluate contents in place". Technically your [] syntax could be used in place of my {} syntax for the exact same interpolation I suggested. The only difference being {} seems a little less ambiguous-- a script may for instance use [$2.00] to represent a dollar amount, {$2.00} would be less likely (though entirely possible). To me the latter seems more obvious as interpolation, anyway...

By the way, I wasn't suggesting the use of (), I was suggesting the use of {}, which in the current grammar must be spaced on either side to be identified as part of control flow. My proposed syntax requires that {} not be spaced, so it could never interfere with the normal use case for braces.
mIRC Arryas by hixxy. Maybe useful?
Originally Posted By: Excalibur
mIRC Arryas by hixxy. Maybe useful?

I wouldn't recommend that snipper to be honest, it's a really slow way of doing it :P

A built in method would be a hell of a lot quicker. I also rewrote that script using hashtables which was a lot faster, don't think I have it now though!
Without looking at that, does it even do what the OP was asking? The OP wasn't really asking about arrays... just dynamic variables.
This isn't actually "backward compatible" (whatever that means), but anyone attempting such a naming scheme should be shot unless the feature is actually there.

Back in the day, I tended to use a style such as:
var %item_ref = $+(%array[,%index,])
; (where %array[ is a variable that contains the literal text %array[)
var %item = $(%item_ref,2)

The main upside is: To change the actual item: set $+(%item_ref) ...
The main downside is: Your suggestion, as it stands, may not be compatible.

You know, the only thing I like about the mIRC scripting language is that it's fluid enough that you can actually come up with quick solutions to things like this, that use minimal amounts of code and are abstract. In fact, I've said it before: you could write an assembly parser that runs in mIRC (with many lines of code). Work with the abstraction, not against it. Make new opportunities, rather than constraints. Otherwise you risk running the mIRC scripting language into the ground.

Here is an example of "user friendly %arrays", as far as "backward compatibility" goes:
if ($FLOOD.TEXT($cid,$chan,$nick).inc >= 10) {
  ; do stuff

By modifying only those parts that can still be "hacked" into older versions of mIRC, you can rest assure that most newer scripts will still run on older versions, and the language stays reasonably consistent.

And the extra script for older versions:
alias FLOOD.TEXT {
  var %name = $+($1,.,$3,.,$2)
  if ($prop == inc) {
    hinc FLOOD.TEXT %name
  if ($isid) {
    return $hget(FLOOD.TEXT,%name)

  ; ... operators here... eg, +=, etc...
Sorry if bumping is not allowed, I just had an idea I felt would be nice to put out.
I think the idea argv provided, by evaluating things within {}'s, can be implemented by something like:

alias set2 { 
  var %a $iif($left($1,1) == -,$2,$1), %b $iif($left($1,1) == -,$3-,$2-)
  set $regsubex(%a,/\{(.+?)\}/gi,$(\1,2)) %b

An example could be:

/set2 %b.{$chan}.{$me} Foo Fahhh
might set %b.#mirc.Firstmate to Foo Fahh
© mIRC Discussion Forums