Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Func-var members

18 views
Skip to first unread message

Rick C. Hodgin

unread,
Dec 28, 2018, 9:05:18 AM12/28/18
to
I had a programming situation today where I'm iterating through some-
thing using a standard int as access into a character string. I have
need at various points to use reference variables to its current value
(as it iterates), to later refer back to the prior value to determine
the length, etc. I was parsing something like this:

aaaa = bbbb + cccc;

I encounter "a" and proceed forward while it's a letter, then I en-
counter a whitespace, and continue forward while it's a whitespace,
and then "b", and then ws, then plus, then ws, then "c", etc. It
was a simple loop, but I had to do it using disparate parts.

It made me think about some abilities that could be added to aid devel-
opers, namely the ability to easily encapsulate variables and functions
related to those variables, both related to their parent, on-the-fly,
something I named "Func-var members" in the subject.

Consider:

int i, i_start, len;

// Iterate through something[] until maxlen (defined
// elsewhere) is attained
for (i = 0; i < maxlen; )
{
if (something[i] == whatever)
{
// Iterate
for (i_start = i, ++i; something[i] == whatever; )
++i;

// Right now, we have i_start, and i is pointing to
// the first character after.
len = i - i_start;
printf("%d bytes\n", len);

} else {
++i;
}
}

Here we see i, i_start, and len, all being related, but there's no
clear indicator of that until you read the code.

What if instead we had the ability to define combination member-
functions + member-variables, using a syntax like this below, using
func() to run the code, or the value itself to reference its value.
The values can also be set using something like i.start = 5;

It can be defined locally, in context, and very simply:

int i {
start { i; ++i }; // Create i.start as this operation
len { i - start }; // Create i.len as this operation
};

// Iterate through something[] until maxlen (defined
// elsewhere) is attained
for (i = 0; i < maxlen; )
{
if (something[i] == whatever)
{
// Iterate
for (i.start(); something[i] == whatever; )
++i;

// Right now, we have i_start, and i is pointing to
// the first character after.
i.len(); // Set the value

printf("%d bytes\n", i.len); // Reference the value

} else {
++i;
}
}

This has the benefit of encapsulating related variables, defining
their operations locally, and creating both functions and variables
with the same name, referenced to their parent where needed:

int i {

// Syntax here is name, followed by {..}, with the lines
// conveying values being assigned to the name, and actual
// code being run as it's encountered

start { i; ++i }; // Creates i.start as this operation
// Usable as i.start() to run, i.start
// to reference its value

len { i - start }; // Creates i.len as this operation
// Usable as i.len() to run, i.len to
// reference its value
};

If a type override is needed, prefix the name and set it, otherwise
it uses the default type of the parent:

int i {
start { i; ++i };
len { i - start };

float proportion { (float)i.len / (float)maxlen };
// Creates i.proportion as this operation
};

Above, start and len are assumed int, while proportion's type is dif-
ferent, so it's explicitly named.

--
Rick C. Hodgin

Rick C. Hodgin

unread,
Dec 28, 2018, 9:28:24 AM12/28/18
to
On 12/28/2018 9:06 AM, Rick C. Hodgin wrote:
>      int i {
>          start { i; ++i };       // Create i.start as this operation
>          len   { i - start };    // Create i.len as this operation
> };

These should probably be defined as:

int i {
start { i++ }; // Loads value, then increments
len { i - start }; // Current i minus the start value
};

--
Rick C. Hodgin

Bart

unread,
Dec 28, 2018, 11:39:57 AM12/28/18
to
On 28/12/2018 14:06, Rick C. Hodgin wrote:

> It can be defined ... very simply:

It's simplicity is eluding me right now...
So here:

int i { fred{++i}}; // declare special function fred
i = 10;
i.fred(); // call fred(), evaluate and store
// ++i, ie. 11
i = 20;
i.fred; // retrieve the value 11
i.fred(); // evaluate ++i (21) and store.

?

If so, what is the advantage to just doing this:

int i, i_fred;
i=10;
i_fred=++i;
i=20;
i_fred;
i_fred=++i;

This seems to be mixing up several concepts: lambdas, function pointers
(if i.start() calls a function, i.start is usually a pointer), local
functions and, I think, closures. For example what happens here:

int a=6;
int i {fred {i+a}};
{ a=8;
double a=9876;
i=10;
i.fred();
....

Does i.fred store 16,18, or 9886.0?

--
bart

Rick C. Hodgin

unread,
Dec 28, 2018, 11:52:39 AM12/28/18
to
On 12/28/2018 11:39 AM, Bart wrote:
> On 28/12/2018 14:06, Rick C. Hodgin wrote:
>>
>>       int i {
>>           start { i++ };
>>           len   { i - start };
>>       };
>>
>>       for (i = 0; i < maxlen; )
>>       {
>>           if (something[i] == whatever)
>>           {
>>               for (i.start(); something[i] == whatever; )
>>                   ++i;
>>               printf("%d bytes\n", i.len());
>>
>>           } else {
>>               ++i;
>>           }
>>       }
>
> So here:
>
>      int i { fred{++i}};       // declare special function fred
>      i = 10;
>      i.fred();                 // call fred(), evaluate and store
>                                // ++i, ie. 11
>      i = 20;
>      i.fred;                   // retrieve the value 11

The use of "i.fred;" would be the same as "i;" on a line by itself.
It has no impacting operation.

>      i.fred();                 // evaluate ++i (21) and store.
>
> ?

Your example would be unfurled as you indicate:

> If so, what is the advantage to just doing this:
>
>      int i, i_fred;
>      i=10;
>      i_fred=++i;
>      i=20;
>      i_fred;
>      i_fred=++i;

Encapsulation, in that "fred" relates to i, and is contextual to i.
It has a direct relationship there, and is encapsulated thusly. It's
also a simple syntax easily conveyed right there at use. It doesn't
require use of #defines to do things. It's not a class defined else-
where. It's for short, local encapsulation of things that are rele-
vant or needed only there in the immediate vicinity.

> This seems to be mixing up several concepts: lambdas, function pointers (if
> i.start() calls a function, i.start is usually a pointer), local functions
> and, I think, closures. For example what happens here:
>
>      int a=6;
>      int i {fred {i+a}};
>      { a=8;
>        double a=9876;
>        i=10;
>        i.fred();
>      ....
>
> Does i.fred store 16,18, or 9886.0?

Whatever's most local in scope to each instance use, so it would
store:

fred = (int)((double)i + a/*9876.0*/);

--
Rick C. Hodgin

0 new messages