Re: Automatially move from $n (was: C++11 move semantics)

2018-09-18 Thread Hans Åberg



> On 18 Sep 2018, at 04:48, Frank Heckenbach  wrote:
> 
> Hans Åberg wrote:
> 
 C++ does not support the implementation of a (tracing) GC, because
 the information needed, though available to the compiler, is not
 available from the language. The fact that it does not have a GC
 is another topic.
>>> 
>>> I know and (again) I don't care because I don't want to use GC
>>> anyway. You're basically discussing with yourself here.
>> 
>> It exemplifies the of limitations C++. See below.
> 
> Nope. Again: compile-time != runtime.

It is funny, below you give a link of people wanting to add unavailable runtime 
information to compile time.

>>> My option? I'm not having this problem.
>> 
>> So then why bother bringing it up in the first place?
> 
> Funnily, I preemptively answered this question just in the next
> sentence that you also quoted:

Hilariously, you rather introduced this new topic, when I discussed something 
else.

>>> Again, I only brought up the
>>> make_pair thing as a counterexample to your claim that an automatic
>>> break would avoid any possible double-move.
>> 
>> You gave a counterexample of something else than what I discussed.
> 
> Nope, you said: "So a way to make it safe is to jump out of the
> action statement.",

That referred to that other feature.

> I replied: "Not necessarily: You could use it
> twice within one expression (unsafe even with jump)", and you
> replied: "That would probably not be possible, if one gets an
> automated break after it." Then I gave an example of what I had said
> before, that it *is* possible to use it twice in one statement,
> counter to your claim. I never said it occured in my code, just
> explained why break isn't the solution.
> 
> You can check it here:
> http://lists.gnu.org/archive/html/bug-bison/2018-09/msg00036.html

Then when you clarified, I decided to follow your topic. 

>>> But it might be a solution to someone else's problem (or another
>>> problem of mine some other day ;).
>> 
>> Until that day, it's too esoteric to be worth implementing, in my opinion.
> 
> Esoteric I don't know, but certainly not hard to implement.
> Basically a flag that it set when moved from and causes an exception
> on any subsequent access (except assignment to, and destruction, of
> course). Seems like a nice student project ... :)

So then implement this compile time check yourself, rather than having lengthy 
discussions here.

> What would be much more interesting would be a generic decorator
> that does this and can be applied to any type one wants to, but
> that's more tricky and I think impossible in current C++ because one
> can't wrap "any method" generically. Maybe if Herb Sutter's
> metaclass proposal takes off, one (far) day ...
> https://herbsutter.com/2017/07/26/metaclasses-thoughts-on-generative-c/
 Even though the compiler may have access to the information to
 check that, you don't have access to that from the language
 itself.
>>> 
>>> - Within(!) the compiler, more general, but a job for compiler
>>> experts, not me.
>> 
>> You won't get that for the same reason as in the GC case above.
> 
> And why would that be? You said yourself that "the compiler may have
> access to the information to check that".

Why don't you check with the GCC people if they want to implement it.





Re: Automatially move from $n (was: C++11 move semantics)

2018-09-17 Thread Frank Heckenbach
Hans Åberg wrote:

> >> C++ does not support the implementation of a (tracing) GC, because
> >> the information needed, though available to the compiler, is not
> >> available from the language. The fact that it does not have a GC
> >> is another topic.
> > 
> > I know and (again) I don't care because I don't want to use GC
> > anyway. You're basically discussing with yourself here.
> 
> It exemplifies the of limitations C++. See below.

Nope. Again: compile-time != runtime.

> > My option? I'm not having this problem.
> 
> So then why bother bringing it up in the first place?

Funnily, I preemptively answered this question just in the next
sentence that you also quoted:

> > Again, I only brought up the
> > make_pair thing as a counterexample to your claim that an automatic
> > break would avoid any possible double-move.
> 
> You gave a counterexample of something else than what I discussed.

Nope, you said: "So a way to make it safe is to jump out of the
action statement.", I replied: "Not necessarily: You could use it
twice within one expression (unsafe even with jump)", and you
replied: "That would probably not be possible, if one gets an
automated break after it." Then I gave an example of what I had said
before, that it *is* possible to use it twice in one statement,
counter to your claim. I never said it occured in my code, just
explained why break isn't the solution.

You can check it here:
http://lists.gnu.org/archive/html/bug-bison/2018-09/msg00036.html

> > But it might be a solution to someone else's problem (or another
> > problem of mine some other day ;).
> 
> Until that day, it's too esoteric to be worth implementing, in my opinion.

Esoteric I don't know, but certainly not hard to implement.
Basically a flag that it set when moved from and causes an exception
on any subsequent access (except assignment to, and destruction, of
course). Seems like a nice student project ... :)

What would be much more interesting would be a generic decorator
that does this and can be applied to any type one wants to, but
that's more tricky and I think impossible in current C++ because one
can't wrap "any method" generically. Maybe if Herb Sutter's
metaclass proposal takes off, one (far) day ...
https://herbsutter.com/2017/07/26/metaclasses-thoughts-on-generative-c/

> >> Even though the compiler may have access to the information to
> >> check that, you don't have access to that from the language
> >> itself.
> > 
> > - Within(!) the compiler, more general, but a job for compiler
> >  experts, not me.
> 
> You won't get that for the same reason as in the GC case above.

And why would that be? You said yourself that "the compiler may have
access to the information to check that".

Regards,
Frank



Re: Automatially move from $n (was: C++11 move semantics)

2018-09-17 Thread Hans Åberg


> On 18 Sep 2018, at 00:20, Frank Heckenbach  wrote:
> 
> Hans Åberg wrote:
> 
 Yes, indeed C++ does not support that,
>>> 
>>> Are you replying to your own statement now? I never claimed (or
>>> cared) whether C++ supports GC.
>> 
>> C++ does not support the implementation of a (tracing) GC, because
>> the information needed, though available to the compiler, is not
>> available from the language. The fact that it does not have a GC
>> is another topic.
> 
> I know and (again) I don't care because I don't want to use GC
> anyway. You're basically discussing with yourself here.

It exemplifies the of limitations C++. See below.

>>> At runtime, yes. Basically an extended unique_ptr could detect this
>>> automatically.
>> 
>> This looks like becoming you option. You might use it for
>> debugging only.
> 
> My option? I'm not having this problem.

So then why bother bringing it up in the first place?

> Again, I only brought up the
> make_pair thing as a counterexample to your claim that an automatic
> break would avoid any possible double-move.

You gave a counterexample of something else than what I discussed.

> But it might be a solution to someone else's problem (or another
> problem of mine some other day ;).

Until that day, it's too esoteric to be worth implementing, in my opinion.

>>> I'd rather see a compile-time check, even if it's a
>>> bit primitive, i.e. gives false positives.
>> 
>> Even though the compiler may have access to the information to
>> check that, you don't have access to that from the language
>> itself. Parsing the language is a long haul, even though there
>> were some here wanting help with that.
> 
> No, I don't want to go there. As said before, I see two viable
> compile-time options so far:
> 
> - Within Bison, hopefully rather easy to implement, but with some
>  false positives.
> 
> - Within(!) the compiler, more general, but a job for compiler
>  experts, not me.

You won't get that for the same reason as in the GC case above.





Re: Automatially move from $n (was: C++11 move semantics)

2018-09-17 Thread Frank Heckenbach
Hans Åberg wrote:

> >> Yes, indeed C++ does not support that,
> > 
> > Are you replying to your own statement now? I never claimed (or
> > cared) whether C++ supports GC.
> 
> C++ does not support the implementation of a (tracing) GC, because
> the information needed, though available to the compiler, is not
> available from the language. The fact that it does not have a GC
> is another topic.

I know and (again) I don't care because I don't want to use GC
anyway. You're basically discussing with yourself here.

> > At runtime, yes. Basically an extended unique_ptr could detect this
> > automatically.
> 
> This looks like becoming you option. You might use it for
> debugging only.

My option? I'm not having this problem. Again, I only brought up the
make_pair thing as a counterexample to your claim that an automatic
break would avoid any possible double-move.

But it might be a solution to someone else's problem (or another
problem of mine some other day ;).

> > I'd rather see a compile-time check, even if it's a
> > bit primitive, i.e. gives false positives.
> 
> Even though the compiler may have access to the information to
> check that, you don't have access to that from the language
> itself. Parsing the language is a long haul, even though there
> were some here wanting help with that.

No, I don't want to go there. As said before, I see two viable
compile-time options so far:

- Within Bison, hopefully rather easy to implement, but with some
  false positives.

- Within(!) the compiler, more general, but a job for compiler
  experts, not me.

Regards,
Frank



Re: Automatially move from $n (was: C++11 move semantics)

2018-09-17 Thread Hans Åberg


> On 17 Sep 2018, at 23:27, Frank Heckenbach  wrote:
> 
> Hans Åberg wrote:
> 
 This illustrates the problem with make_pair($x, $x): one may try a
 reference count or GC, but C++ does not support the implementation
 of a GC, even though the compiler has the required information, it
 is not accessible from the language.
>>> 
>>> Hold it! We were discussing a static compiler check, and within two
>>> paragraphs you divert to runtime checks (which are less reliable)
>>> and then to GC which I dislike for many reasons. To me it seems like
>>> a last effort: if you can't do proper resource management (like
>>> RAII), let the garbage collector pick up the pieces.
>> 
>> Yes, indeed C++ does not support that,
> 
> Are you replying to your own statement now? I never claimed (or
> cared) whether C++ supports GC.

C++ does not support the implementation of a (tracing) GC, because the 
information needed, though available to the compiler, is not available from the 
language. The fact that it does not have a GC is another topic.

>>> Fact is, I can
>>> do proper resource management in most cases, and just said it would
>>> be nice to have an extra check if it's not too hard to implement.
>> 
>> It looks is not hard to implement such a check against double
>> moves, and that might be the best solution, though it calls for
>> more careful runtime testing.
> 
> At runtime, yes. Basically an extended unique_ptr could detect this
> automatically.

This looks like becoming you option. You might use it for debugging only. By 
contrast, a reference count cannot be optimized away, so this might be better.

> I'd rather see a compile-time check, even if it's a
> bit primitive, i.e. gives false positives.

Even though the compiler may have access to the information to check that, you 
don't have access to that from the language itself. Parsing the language is a 
long haul, even though there were some here wanting help with that. There are 
LALR C++ grammars out there at least for some earlier language version.





Re: Automatially move from $n (was: C++11 move semantics)

2018-09-17 Thread Frank Heckenbach
Hans Åberg wrote:

> >>> As I said, this already happens in "$$ = foo ();" (automatially) and
> >>> "$$ = std::move ($k);" (whether the move is explicit or
> >>> automatically inserted as we're discussing). So if $k is covered, no
> >>> special handling for $$ seems necessary.
> >> 
> >> You can do it by hand,
> > 
> > Sorry, but how does this answer anything? The subject (also thread
> > subject) is explicitly: "Automatially[sic, sorry for the typo ;]
> > move from $n".
> > 
> > So saying "You can do it by hand" is just giving up (which is
> > pointless, since I already have a solution).
> 
> It looks as though you are suggesting doing it by hand by writing
> $$ = std::move($k) instead of $$ = $k whenever necessary.

I'm suggesting doing it automatically (again, see subject).

> I considered having it automatically.

You focus on one special case (moving $k to $$). You seem to think
it's somehow different to moving $k to somewhere else, but you
failed to explain why this should be so. I think it's the same, so
solving the general case (moving from $k) will also solve the
special case (moving $k to $$).

> > I can't help but view your insisting on $$ as diverting from the
> > actual topic. If you want to discuss any issues with moving to $$
> > (whatever those issues may be; I don't see any), may I suggest you
> > start a new thread, please?
> 
> You are the one keeping comping back to the issue,

It's you who keeps coming back to $$ again and again.

> despite I told you I now see that you are interested in  something
> else.

Not something else, just a more general case.

> >> This illustrates the problem with make_pair($x, $x): one may try a
> >> reference count or GC, but C++ does not support the implementation
> >> of a GC, even though the compiler has the required information, it
> >> is not accessible from the language.
> > 
> > Hold it! We were discussing a static compiler check, and within two
> > paragraphs you divert to runtime checks (which are less reliable)
> > and then to GC which I dislike for many reasons. To me it seems like
> > a last effort: if you can't do proper resource management (like
> > RAII), let the garbage collector pick up the pieces.
> 
> Yes, indeed C++ does not support that,

Are you replying to your own statement now? I never claimed (or
cared) whether C++ supports GC.

> and it looks it is the same with your problem for the same
> reasons, which is why it is so difficult to find solutions within
> the language.

I don't think so. GC needs type information at runtime. An optimizer
needs it at compile type. I don't know if it has access to it
already (don't know gcc internals so well), but if not, providing it
is something totally different from providing it to the runtime.

> > Fact is, I can
> > do proper resource management in most cases, and just said it would
> > be nice to have an extra check if it's not too hard to implement.
> 
> It looks is not hard to implement such a check against double
> moves, and that might be the best solution, though it calls for
> more careful runtime testing.

At runtime, yes. Basically an extended unique_ptr could detect this
automatically. I'd rather see a compile-time check, even if it's a
bit primitive, i.e. gives false positives.

Regards,
Frank



Re: Automatially move from $n (was: C++11 move semantics)

2018-09-16 Thread Hans Åberg


> On 16 Sep 2018, at 19:16, Frank Heckenbach  wrote:
> 
> Hans Åberg wrote:
> 
 Maybe not for you, but for a more normal use, with types having
 both copy and move. Then one would like to use move to $$ whenever
 possible. Doesn't matter with me, as it is just some pointers and
 integers.
>>> 
>>> As I said, this already happens in "$$ = foo ();" (automatially) and
>>> "$$ = std::move ($k);" (whether the move is explicit or
>>> automatically inserted as we're discussing). So if $k is covered, no
>>> special handling for $$ seems necessary.
>> 
>> You can do it by hand,
> 
> Sorry, but how does this answer anything? The subject (also thread
> subject) is explicitly: "Automatially[sic, sorry for the typo ;]
> move from $n".
> 
> So saying "You can do it by hand" is just giving up (which is
> pointless, since I already have a solution).

It looks as though you are suggesting doing it by hand by writing $$ = 
std::move($k) instead of $$ = $k whenever necessary. I considered having it 
automatically.

>> but the case I considered was to find an automated approach
>> without explicitly calling std::move in $$ = $k. But your case is
>> different.
> 
> It's more general. "$$ = $k" is strictly a subset of the general
> case. (And IMHO not a very important one for k > 1. For k = 1, we
> can have a default action, but how often do you really need
> "$$ = $2"? In a rule like "expr = '(' expr ')';" typically, but
> that's about it.)

It happens every now and again. I have
  identifier_declaration definition[x]
where the first just defines the names and does not produce any value.

> I can't help but view your insisting on $$ as diverting from the
> actual topic. If you want to discuss any issues with moving to $$
> (whatever those issues may be; I don't see any), may I suggest you
> start a new thread, please?

You are the one keeping comping back to the issue, despite I told you I now see 
that you are interested in  something else.

 No, but it seems me it is a hard problem. A compiler optimizer can
 recognize such things if it has sufficient information about the
 types, by tracing the code flow.
>>> 
>>> Yes, perhaps we should ignore the issue for now and hope for
>>> compilers to offer such a warning in the future (which would be more
>>> useful anyway, since it would work for all code, not only Bison
>>> grammars).
>> 
>> You might make, for debugging purposes, a simplified version of a
>> reference count, a boolean that tells whether the object has been
>> moved, and issue an error if moved again, or otherwise just have a
>> moved from state with such a property.
>> 
>> This illustrates the problem with make_pair($x, $x): one may try a
>> reference count or GC, but C++ does not support the implementation
>> of a GC, even though the compiler has the required information, it
>> is not accessible from the language.
> 
> Hold it! We were discussing a static compiler check, and within two
> paragraphs you divert to runtime checks (which are less reliable)
> and then to GC which I dislike for many reasons. To me it seems like
> a last effort: if you can't do proper resource management (like
> RAII), let the garbage collector pick up the pieces.

Yes, indeed C++ does not support that, and it looks it is the same with your 
problem for the same reasons, which is why it is so difficult to find solutions 
within the language.

> Fact is, I can
> do proper resource management in most cases, and just said it would
> be nice to have an extra check if it's not too hard to implement.

It looks is not hard to implement such a check against double moves, and that 
might be the best solution, though it calls for more careful runtime testing.

> Also note that "make_pair($x, $x)" was just a counterexample to your
> claim that an automatic break after the statement would avoid the
> problem. It's not something I actually need to do. If I did, I could
> choose between copying in this case (if possible), using a
> shared_ptr, or whatever.

Yes of course, I have a polymorphic (virtual) ref GC type that emulates T& 
holding just a non-null pointer, and one might need to clone the value 
sometimes.





Re: Automatially move from $n (was: C++11 move semantics)

2018-09-16 Thread Frank Heckenbach
Hans Åberg wrote:

> >> Maybe not for you, but for a more normal use, with types having
> >> both copy and move. Then one would like to use move to $$ whenever
> >> possible. Doesn't matter with me, as it is just some pointers and
> >> integers.
> > 
> > As I said, this already happens in "$$ = foo ();" (automatially) and
> > "$$ = std::move ($k);" (whether the move is explicit or
> > automatically inserted as we're discussing). So if $k is covered, no
> > special handling for $$ seems necessary.
> 
> You can do it by hand,

Sorry, but how does this answer anything? The subject (also thread
subject) is explicitly: "Automatially[sic, sorry for the typo ;]
move from $n".

So saying "You can do it by hand" is just giving up (which is
pointless, since I already have a solution).

> but the case I considered was to find an automated approach
> without explicitly calling std::move in $$ = $k. But your case is
> different.

It's more general. "$$ = $k" is strictly a subset of the general
case. (And IMHO not a very important one for k > 1. For k = 1, we
can have a default action, but how often do you really need
"$$ = $2"? In a rule like "expr = '(' expr ')';" typically, but
that's about it.)

I can't help but view your insisting on $$ as diverting from the
actual topic. If you want to discuss any issues with moving to $$
(whatever those issues may be; I don't see any), may I suggest you
start a new thread, please?

> >> No, but it seems me it is a hard problem. A compiler optimizer can
> >> recognize such things if it has sufficient information about the
> >> types, by tracing the code flow.
> > 
> > Yes, perhaps we should ignore the issue for now and hope for
> > compilers to offer such a warning in the future (which would be more
> > useful anyway, since it would work for all code, not only Bison
> > grammars).
> 
> You might make, for debugging purposes, a simplified version of a
> reference count, a boolean that tells whether the object has been
> moved, and issue an error if moved again, or otherwise just have a
> moved from state with such a property.
> 
> This illustrates the problem with make_pair($x, $x): one may try a
> reference count or GC, but C++ does not support the implementation
> of a GC, even though the compiler has the required information, it
> is not accessible from the language.

Hold it! We were discussing a static compiler check, and within two
paragraphs you divert to runtime checks (which are less reliable)
and then to GC which I dislike for many reasons. To me it seems like
a last effort: if you can't do proper resource management (like
RAII), let the garbage collector pick up the pieces. Fact is, I can
do proper resource management in most cases, and just said it would
be nice to have an extra check if it's not too hard to implement.

Also note that "make_pair($x, $x)" was just a counterexample to your
claim that an automatic break after the statement would avoid the
problem. It's not something I actually need to do. If I did, I could
choose between copying in this case (if possible), using a
shared_ptr, or whatever.

Regards,
Frank



Re: Automatially move from $n (was: C++11 move semantics)

2018-09-16 Thread Hans Åberg


> On 16 Sep 2018, at 17:38, Frank Heckenbach  wrote:
> 
> Hans Åberg wrote:

>>> (*) Nitpick: Except in a case like "$$ = $2;", but then I'd argue
>>>   it's the passing of $2 to $$'s assignment operator that's the
>>>   issue. :)
>> 
>> Maybe not for you, but for a more normal use, with types having
>> both copy and move. Then one would like to use move to $$ whenever
>> possible. Doesn't matter with me, as it is just some pointers and
>> integers.
> 
> As I said, this already happens in "$$ = foo ();" (automatially) and
> "$$ = std::move ($k);" (whether the move is explicit or
> automatically inserted as we're discussing). So if $k is covered, no
> special handling for $$ seems necessary.

You can do it by hand, but the case I considered was to find an automated 
approach without explicitly calling std::move in $$ = $k. But your case is 
different.

>> No, but it seems me it is a hard problem. A compiler optimizer can
>> recognize such things if it has sufficient information about the
>> types, by tracing the code flow.
> 
> Yes, perhaps we should ignore the issue for now and hope for
> compilers to offer such a warning in the future (which would be more
> useful anyway, since it would work for all code, not only Bison
> grammars).

You might make, for debugging purposes, a simplified version of a reference 
count, a boolean that tells whether the object has been moved, and issue an 
error if moved again, or otherwise just have a moved from state with such a 
property.

This illustrates the problem with make_pair($x, $x): one may try a reference 
count or GC, but C++ does not support the implementation of a GC, even though 
the compiler has the required information, it is not accessible from the 
language.

>>> On the same token, Bison could then also (optionally) warn if some
>>> $k which has a type is not used. I don't know if there is interest
>>> in such a feature. It could also be useful for other languages.
>>> 
>>> It might not be too hard to do for someone who's familiar with
>>> Bison's internals. (Unfortunately, I'm not very much, and don't have
>>> much free time right now.)
>> 
>> How would this be different from the current static type system?
> 
> The type system wouldn't change. Just an additional check:
> 
>  expr: expr '+' expr { $$ = $1; };
> 
> Obviously one forgot to use $3 here which has a type (unlike $2
> which doesn't have a type and so is not expected to be used).
> 
> Bison could detect and warn about this (proably optional, since I
> guess some people declare semantic types that are only meant to be
> used sometimes).

I use explicitly named variables, which guards against using the wrong $k 
number when changing a rule:
  expr: expr[x] "+" expr[y] { $$ = $x + $y; };

It would then, I gather, be easy to warn if such explicit name are unused, as 
Bison already checks if one is using undefined names.





Re: Automatially move from $n (was: C++11 move semantics)

2018-09-16 Thread Frank Heckenbach
Hans Åberg wrote:

> >> Ah, your idea is to wrap std::move around the $k values! My idea
> >> is to let the C++ language recognise that, and then automate the
> >> assignment to $$.
> > 
> > Again, the assignment to $$ is *NOT* the issue! (*)
> > It's the passing (moving) of $k.
> > 
> > (*) Nitpick: Except in a case like "$$ = $2;", but then I'd argue
> >it's the passing of $2 to $$'s assignment operator that's the
> >issue. :)
> 
> Maybe not for you, but for a more normal use, with types having
> both copy and move. Then one would like to use move to $$ whenever
> possible. Doesn't matter with me, as it is just some pointers and
> integers.

As I said, this already happens in "$$ = foo ();" (automatially) and
"$$ = std::move ($k);" (whether the move is explicit or
automatically inserted as we're discussing). So if $k is covered, no
special handling for $$ seems necessary.

> > You mean some kind of code analyzer? This might be possible, but may
> > be overkill.
> 
> Yes, you might check how people do check against that problem, if
> there is some program doing that. Then one might get ideas of how
> to get into Bison.
> 
> Perhaps it might be possible to have some DLL or external program and invoke 
> that.

If you know of one, let me know. (And it would have to be
GPL-compatible in order to link it into Bison.)

> No, but it seems me it is a hard problem. A compiler optimizer can
> recognize such things if it has sufficient information about the
> types, by tracing the code flow.

Yes, perhaps we should ignore the issue for now and hope for
compilers to offer such a warning in the future (which would be more
useful anyway, since it would work for all code, not only Bison
grammars).

> > On the same token, Bison could then also (optionally) warn if some
> > $k which has a type is not used. I don't know if there is interest
> > in such a feature. It could also be useful for other languages.
> > 
> > It might not be too hard to do for someone who's familiar with
> > Bison's internals. (Unfortunately, I'm not very much, and don't have
> > much free time right now.)
> 
> How would this be different from the current static type system?

The type system wouldn't change. Just an additional check:

  expr: expr '+' expr { $$ = $1; };

Obviously one forgot to use $3 here which has a type (unlike $2
which doesn't have a type and so is not expected to be used).

Bison could detect and warn about this (proably optional, since I
guess some people declare semantic types that are only meant to be
used sometimes).

Regards,
Frank



Re: Automatially move from $n (was: C++11 move semantics)

2018-09-16 Thread Frank Heckenbach
Akim Demaille wrote:

> > As I wrote, if Bison could detect multiple uses and warn, that would
> > be great, but I didn't look into it as I didn't want to patch Bison
> > itself.
> 
> Agreed.  But then, the syntax you choose, is a little weird:
> the syntax is quite generic (we apply some treatment to $k,
> which could be for instance printing its value (stupid, but
> why not)), but the warning would be really specific for move.

Indeed, I had considered both things separately, but together they
don't make too much sense.

> Shouldn't we go for something like %define api.value.move,
> or api.rhs.move, or api.rhs.rvalue, etc.  I mean, as a Boolean
> value, not a generic placeholder.

Might be better then (and would work for me, of course). Unless
someone comes up with another valid use of the more generic feature
(then we'd have to see how the warning would interact with it).

Regards,
Frank



Re: Automatially move from $n (was: C++11 move semantics)

2018-09-16 Thread Akim Demaille



> Le 15 sept. 2018 à 19:15, Frank Heckenbach  a écrit :
> 
> Akim Demaille wrote:
> 
>> Would you recommend that we really import this into Bison?
> 
> I would. My grammar file is much more readable with it, as it saves
> me multiple std::move calls in most rules.

Great, thanks for the input!

> As I wrote, if Bison could detect multiple uses and warn, that would
> be great, but I didn’t look into it as I didn't want to patch Bison
> itself.

Agreed.  But then, the syntax you choose, is a little weird:
the syntax is quite generic (we apply some treatment to $k,
which could be for instance printing its value (stupid, but
why not)), but the warning would be really specific for move.

Shouldn’t we go for something like %define api.value.move,
or api.rhs.move, or api.rhs.rvalue, etc.  I mean, as a Boolean
value, not a generic placeholder.

First let’s decide what is the feature, then we’ll find the
proper name :)

> Another syntax (just for the sake of example "#1" for moving, while
> keeping "$1" as is) might be an idea, but is still dangerous if one
> uses $1 after #1, so probably not worth it.
> 
> So, lacking other ideas, I'd stay with api.rhs.access, which was
> easy to implement and does the job for me. I certainly don't want to
> put std::move everywhere in my grammar. -- In fact, if I'd
> ultimately have to, I'd make make up something like "#1" and
> preprocess my grammar with sed before feeding it to Bison, to keep
> it readable. Seeing as Bison does lots of processing of the source
> anyway, this would seem overly complicated and bizarre to me.

I don’t think Bison’s should have more special characters.
#define M std::move can make it light enough, but I agree
with adding automove.


Re: Automatially move from $n (was: C++11 move semantics)

2018-09-15 Thread Hans Åberg


> On 16 Sep 2018, at 01:01, Frank Heckenbach  wrote:
> 
> Hans Åberg wrote:
> 
>> I realize now that you want to wrap $k with std::move and guard against 
>> reuse of that! (See below)
> 
> Yes, see $subject.
> 
>>> Sure it's possible: "make_pair ($1, $1)". Don't do that with
>>> automatic move!
>> 
>> Ah, your idea is to wrap std::move around the $k values! My idea
>> is to let the C++ language recognise that, and then automate the
>> assignment to $$.
> 
> Again, the assignment to $$ is *NOT* the issue! (*)
> It's the passing (moving) of $k.
> 
> (*) Nitpick: Except in a case like "$$ = $2;", but then I'd argue
>it's the passing of $2 to $$'s assignment operator that's the
>issue. :)

Maybe not for you, but for a more normal use, with types having both copy and 
move. Then one would like to use move to $$ whenever possible. Doesn't matter 
with me, as it is just some pointers and integers.

>> Maybe there is some more general C++ code checking program that
>> can be linked into Bison to check the  actions.
> 
> You mean some kind of code analyzer? This might be possible, but may
> be overkill.

Yes, you might check how people do check against that problem, if there is some 
program doing that. Then one might get ideas of how to get into Bison.

Perhaps it might be possible to have some DLL or external program and invoke 
that.

> Bison could keep track if any $k is used several times
> and warn about that; though it may give false positives in cases
> such as:
> 
>  $$ = $1 ? foo (move ($2)) : bar (move ($2));  // safe
> 
> But the user could work around such (hopefully) rare cases with a
> temporary variable holding move ($2).
> 
> Or can code analyzers recognize the above as safe? (Do you have
> experience with any?)

No, but it seems me it is a hard problem. A compiler optimizer can recognize 
such things if it has sufficient information about the types, by tracing the 
code flow.

> On the same token, Bison could then also (optionally) warn if some
> $k which has a type is not used. I don't know if there is interest
> in such a feature. It could also be useful for other languages.
> 
> It might not be too hard to do for someone who's familiar with
> Bison's internals. (Unfortunately, I'm not very much, and don't have
> much free time right now.)

How would this be different from the current static type system?





Re: Automatially move from $n (was: C++11 move semantics)

2018-09-15 Thread Frank Heckenbach
Hans Åberg wrote:

> I realize now that you want to wrap $k with std::move and guard against reuse 
> of that! (See below)

Yes, see $subject.

> > Sure it's possible: "make_pair ($1, $1)". Don't do that with
> > automatic move!
> 
> Ah, your idea is to wrap std::move around the $k values! My idea
> is to let the C++ language recognise that, and then automate the
> assignment to $$.

Again, the assignment to $$ is *NOT* the issue! (*)
It's the passing (moving) of $k.

(*) Nitpick: Except in a case like "$$ = $2;", but then I'd argue
it's the passing of $2 to $$'s assignment operator that's the
issue. :)

> Maybe there is some more general C++ code checking program that
> can be linked into Bison to check the  actions.

You mean some kind of code analyzer? This might be possible, but may
be overkill. Bison could keep track if any $k is used several times
and warn about that; though it may give false positives in cases
such as:

  $$ = $1 ? foo (move ($2)) : bar (move ($2));  // safe

But the user could work around such (hopefully) rare cases with a
temporary variable holding move ($2).

Or can code analyzers recognize the above as safe? (Do you have
experience with any?)

On the same token, Bison could then also (optionally) warn if some
$k which has a type is not used. I don't know if there is interest
in such a feature. It could also be useful for other languages.

It might not be too hard to do for someone who's familiar with
Bison's internals. (Unfortunately, I'm not very much, and don't have
much free time right now.)

Regards,
Frank



Re: Automatially move from $n (was: C++11 move semantics)

2018-09-15 Thread Hans Åberg


> On 16 Sep 2018, at 00:18, Frank Heckenbach  wrote:
> 
> Hans Åberg wrote:
> 
>>case k:
>>  auto action_k = [...](){ ... return ...; };
>>  $$ = std::move(action_k(...));
> 
> I think you're at "$$" again rather than "$1" etc. I think we had
> cleared that up.

I realize now that you want to wrap $k with std::move and guard against reuse 
of that! (See below)

 So a way to make it safe is to jump out of the action statement.
>>> 
>>> Not necessarily: You could use it twice within one expression
>>> (unsafe even with jump)
>> 
>> That would probably not be possible, if one gets an automated break after it.
> 
> Sure it's possible: "make_pair ($1, $1)". Don't do that with
> automatic move!

Ah, your idea is to wrap std::move around the $k values! My idea is to let the 
C++ language recognise that, and then automate the assignment to $$.

If you have a move only type and want it to safe as above, then you need some 
more general C++ checking mechanism.

>>> or just not use it twice (safe even without
>>> jump).
>> 
>> But then one has to find a way to guard against that.
> 
> So far, the guard would have to be the programmer. (Which is not
> completely different from explicit std::move where one also needs to
> be careful. C++ is not BASIC. ;)
> 
> If Bison can detect it automatically, that would be nice, but
> otherwise demanding some responsibility by the programmer seems
> acceptable.

Maybe there is some more general C++ code checking program that can be linked 
into Bison to check the  actions.

 But that just applies it always, which might be safe for your move only 
 type,
>>> 
>>> In fact it's safe for copy-only types, and possibly unsafe precisely
>>> for movable types (move-only or move-and-copyable).
>> 
>> It is always unsafe with moves, unless one can find a guard against 
>> unintentional reuse of a moved-from element.
> 
> "always ... unless" = "possibly" :)

Indeed you have a lot of code, and then somebody sometime in the future should 
check it, perhaps yourself, and have forgotten about the details.





Re: Automatially move from $n (was: C++11 move semantics)

2018-09-15 Thread Frank Heckenbach
Hans Åberg wrote:

> >> But you can't safely or in general have Bison writing $$ =
> >> std::move(a) directly as one might do something else to a
> >> afterwards.
> > 
> > It would be safe if Bison checked that it's used only once in the
> > action.
> 
> But in view of that is complicated, I was playing along with idea
> to somehow using C++ to recognize it. The only way seems to use
> function calls and return, as assignments can be applied more than
> once. So the idea is that if Bison now writes

>   switch (yyn) {
> ... 
> case k:
> {
>   ...
> }   
>   }
> where the action may have $$ = ..., one has
> case k:
>   $$ = std::move(action_k(...));
> where the action_k is some function where one returns the value instead. I'm 
> not sure exactly how to pick it together, perhaps fitting a lambda capture
> case k:
>   auto action_k = [...](){ ... return ...; };
>   $$ = std::move(action_k(...));

I think you're at "$$" again rather than "$1" etc. I think we had
cleared that up.

> >> So a way to make it safe is to jump out of the action statement.
> > 
> > Not necessarily: You could use it twice within one expression
> > (unsafe even with jump)
> 
> That would probably not be possible, if one gets an automated break after it.

Sure it's possible: "make_pair ($1, $1)". Don't do that with
automatic move!

> > or just not use it twice (safe even without
> > jump).
> 
> But then one has to find a way to guard against that.

So far, the guard would have to be the programmer. (Which is not
completely different from explicit std::move where one also needs to
be careful. C++ is not BASIC. ;)

If Bison can detect it automatically, that would be nice, but
otherwise demanding some responsibility by the programmer seems
acceptable.

> >> But that just applies it always, which might be safe for your move only 
> >> type,
> > 
> > In fact it's safe for copy-only types, and possibly unsafe precisely
> > for movable types (move-only or move-and-copyable).
> 
> It is always unsafe with moves, unless one can find a guard against 
> unintentional reuse of a moved-from element.

"always ... unless" = "possibly" :)

Regards,
Frank



Re: Automatially move from $n (was: C++11 move semantics)

2018-09-15 Thread Hans Åberg


> On 15 Sep 2018, at 23:26, Frank Heckenbach  wrote:
> 
> Hans Åberg wrote:
> 
>> But you can't safely or in general have Bison writing $$ =
>> std::move(a) directly as one might do something else to a
>> afterwards.
> 
> It would be safe if Bison checked that it's used only once in the
> action.

But in view of that is complicated, I was playing along with idea to somehow 
using C++ to recognize it. The only way seems to use function calls and return, 
as assignments can be applied more than once. So the idea is that if Bison now 
writes
  switch (yyn) {
… 
case k:
{
  …
}   
  }
where the action may have $$ = …, one has
case k:
  $$ = std::move(action_k(…));
where the action_k is some function where one returns the value instead. I'm 
not sure exactly how to pick it together, perhaps fitting a lambda capture
case k:
  auto action_k = […](){ … return …; };
  $$ = std::move(action_k(…));

>> So a way to make it safe is to jump out of the action statement.
> 
> Not necessarily: You could use it twice within one expression
> (unsafe even with jump)

That would probably not be possible, if one gets an automated break after it.

> or just not use it twice (safe even without
> jump).

But then one has to find a way to guard against that.

>>> What I want (or actually have, since I imeplented it :) is a way to
>>> make Bison apply std::move automatically.
>> 
>> But that just applies it always, which might be safe for your move only type,
> 
> In fact it's safe for copy-only types, and possibly unsafe precisely
> for movable types (move-only or move-and-copyable).

It is always unsafe with moves, unless one can find a guard against 
unintentional reuse of a moved-from element.





Re: Automatially move from $n (was: C++11 move semantics)

2018-09-15 Thread Frank Heckenbach
Hans Åberg wrote:

> But you can't safely or in general have Bison writing $$ =
> std::move(a) directly as one might do something else to a
> afterwards.

It would be safe if Bison checked that it's used only once in the
action.

> So a way to make it safe is to jump out of the action statement.

Not necessarily: You could use it twice within one expression
(unsafe even with jump) or just not use it twice (safe even without
jump).

> > What I want (or actually have, since I imeplented it :) is a way to
> > make Bison apply std::move automatically.
> 
> But that just applies it always, which might be safe for your move only type,

In fact it's safe for copy-only types, and possibly unsafe precisely
for movable types (move-only or move-and-copyable).

> but is not safe in general, right?

Right, that't why I made it opt-in by setting api.rhs.access.

Regards,
Frank



Re: Automatially move from $n (was: C++11 move semantics)

2018-09-15 Thread Hans Åberg


> On 15 Sep 2018, at 22:56, Frank Heckenbach  wrote:
> 
> You don't need h at all.
> 
> Simply "b = std::move (a);" will do the same. All it does is convert
> a to an rvalue reference. If A has a move assignment operator, this
> will be chosen, if it doesn't but a copy assignment operator, that
> one will be chosen. That's all standard C++ behaviour.

But you can't safely or in general have Bison writing $$ = std::move(a) 
directly as one might do something else to a afterwards. So a way to make it 
safe is to jump out of the action statement. Using functions and returns is 
probably not a good idea because one would have to capture variables in the 
action.

> What I want (or actually have, since I imeplented it :) is a way to
> make Bison apply std::move automatically.

But that just applies it always, which might be safe for your move only type, 
but is not safe in general, right?




Re: Automatially move from $n (was: C++11 move semantics)

2018-09-15 Thread Frank Heckenbach
Hans Åberg wrote:

> If I write:
> 
> A& h(A& a) {
>   return a;
> }
> 
> A&& h(A&& a) {
>   return std::move(a);
> }

h seems like a NOP.

> int main() {
>   A a, b;
> 
>   b = std::move(h(a));
>   b = std::move(h(std::move(a)));

You don't need "std::move" twice here.

>   return EXIT_SUCCESS;
> }
> 
> Then if A only has copy assignment, that will be used, but if has
> that and move assignment or only move assignment, then move
> assignment will be used. No copying occurs with copy elision.

You don't need h at all.

Simply "b = std::move (a);" will do the same. All it does is convert
a to an rvalue reference. If A has a move assignment operator, this
will be chosen, if it doesn't but a copy assignment operator, that
one will be chosen. That's all standard C++ behaviour.

> Isn't that what you want?

What I want (or actually have, since I imeplented it :) is a way to
make Bison apply std::move automatically.

Regards,
Frank



Re: Automatially move from $n (was: C++11 move semantics)

2018-09-15 Thread Hans Åberg


On 15 Sep 2018, at 22:10, Frank Heckenbach  wrote:
> 
> Hans Åberg wrote:
> 
>> The idea would be to write something equivalent to
>> return make_unique($1, $2, $3);
>> and the Bison writes something like
>> $$ = std::move(action_k(...return make_unique($1, $2, $3);...))
> 
> I don't follow you. What is action_k, and how would that cause
> moving from $1 etc.?
 
 Action k in the switch statement.
>>> 
>>> Huh? I really don't get what your proposed syntax is supposed to
>>> mean. Is action_k supposed to be a lambda (what else could appear in
>>> an expression and contain a statement inside)? What would it do?
>> 
>> Just produce an r-value.
> 
> Again:
> 
> - make_unique already produces an rvalue
> 
> - (I'll ignore the "...return", since you didn't comment on it, I
>  assume it's a typo)
> 
> - Then, you say, action_k produces an rvalue, from an rvalue?
> 
> - Finally, std::move takes this rvalue and turns it into an rvalue
>  (because that's what std::move does).
> 
> Do you want a triple-r-value?
> 
> Sorry if I'm a bit cynical meanwhile, but I said I don't follow what
> you intend to do, so it would be nice to explain it with something
> more than half a sentence, really.

If I write:

A& h(A& a) {
  return a;
}

A&& h(A&& a) {
  return std::move(a);
}

int main() {
  A a, b;

  b = std::move(h(a));
  b = std::move(h(std::move(a)));

  return EXIT_SUCCESS;
}

Then if A only has copy assignment, that will be used, but if has that and move 
assignment or only move assignment, then move assignment will be used. No 
copying occurs with copy elision. Isn't that what you want?





Re: Automatially move from $n (was: C++11 move semantics)

2018-09-15 Thread Frank Heckenbach
Hans Åberg wrote:

>  The idea would be to write something equivalent to
>  return make_unique($1, $2, $3);
>  and the Bison writes something like
>  $$ = std::move(action_k(...return make_unique($1, $2, $3);...))
> >>> 
> >>> I don't follow you. What is action_k, and how would that cause
> >>> moving from $1 etc.?
> >> 
> >> Action k in the switch statement.
> > 
> > Huh? I really don't get what your proposed syntax is supposed to
> > mean. Is action_k supposed to be a lambda (what else could appear in
> > an expression and contain a statement inside)? What would it do?
> 
> Just produce an r-value.

Again:

- make_unique already produces an rvalue

- (I'll ignore the "...return", since you didn't comment on it, I
  assume it's a typo)

- Then, you say, action_k produces an rvalue, from an rvalue?

- Finally, std::move takes this rvalue and turns it into an rvalue
  (because that's what std::move does).

Do you want a triple-r-value?

Sorry if I'm a bit cynical meanwhile, but I said I don't follow what
you intend to do, so it would be nice to explain it with something
more than half a sentence, really.

> >> Move operators were originally designed to avoid copying in returns.
> > 
> > I don't know if this was so or not originally, but I'm talking about
> > moving arguments, not return values. That's what I've been saying
> > the whole time, including the thread subject! Moving the return
> > value is no big problem most of the time: "$$ = make_unique ..."
> > works without any std::move because a function result(*) is
> > automatically an rvalue.
> 
> The idea is to create an r-value situation, which then translates into a move 
> assignment.

Again, make_unique already "creates an rvalue situation".

And, also again, how does any of that help with moving from $1, $2
etc. which is the actual topic?

Regards,
Frank



Re: Automatially move from $n (was: C++11 move semantics)

2018-09-15 Thread Hans Åberg


> On 15 Sep 2018, at 21:57, Frank Heckenbach  wrote:
> 
> Hans Åberg wrote:
> 
 The idea would be to write something equivalent to
 return make_unique($1, $2, $3);
 and the Bison writes something like
 $$ = std::move(action_k(...return make_unique($1, $2, $3);...))
>>> 
>>> I don't follow you. What is action_k, and how would that cause
>>> moving from $1 etc.?
>> 
>> Action k in the switch statement.
> 
> Huh? I really don't get what your proposed syntax is supposed to
> mean. Is action_k supposed to be a lambda (what else could appear in
> an expression and contain a statement inside)? What would it do?

Just produce an r-value.

>> Move operators were originally designed to avoid copying in returns.
> 
> I don't know if this was so or not originally, but I'm talking about
> moving arguments, not return values. That's what I've been saying
> the whole time, including the thread subject! Moving the return
> value is no big problem most of the time: "$$ = make_unique ..."
> works without any std::move because a function result(*) is
> automatically an rvalue.

The idea is to create an r-value situation, which then translates into a move 
assignment.




Re: Automatially move from $n (was: C++11 move semantics)

2018-09-15 Thread Frank Heckenbach
Hans Åberg wrote:

> >> The idea would be to write something equivalent to
> >>  return make_unique($1, $2, $3);
> >> and the Bison writes something like
> >>  $$ = std::move(action_k(...return make_unique($1, $2, $3);...))
> > 
> > I don't follow you. What is action_k, and how would that cause
> > moving from $1 etc.?
> 
> Action k in the switch statement.

Huh? I really don't get what your proposed syntax is supposed to
mean. Is action_k supposed to be a lambda (what else could appear in
an expression and contain a statement inside)? What would it do?

> Move operators were originally designed to avoid copying in returns.

I don't know if this was so or not originally, but I'm talking about
moving arguments, not return values. That's what I've been saying
the whole time, including the thread subject! Moving the return
value is no big problem most of the time: "$$ = make_unique ..."
works without any std::move because a function result(*) is
automatically an rvalue.

(*) Nitpick: unless it's declared of lvalue-reference type which is
not the case here.

I'm afrading you're barking up the wrong tree.

Regards,
Frank



Re: Automatially move from $n (was: C++11 move semantics)

2018-09-15 Thread Hans Åberg


> On 15 Sep 2018, at 21:25, Frank Heckenbach  wrote:
> 
> Hans Åberg wrote:

>> The idea would be to write something equivalent to
>>  return make_unique($1, $2, $3);
>> and the Bison writes something like
>>  $$ = std::move(action_k(...return make_unique($1, $2, $3);...))
> 
> I don't follow you. What is action_k, and how would that cause
> moving from $1 etc.?

Action k in the switch statement. Move operators were originally designed to 
avoid copying in returns.

>> Even in view of copy elision, default in C++17 [1], this would be safe, 
>> because one cannot move an already moved object by mistake.
> 
> Why not?

Because it breaks the execution path, so one cannot apply it twice to the same 
value.

>> As the point is breaking out of the execution path, one might use your 
>> suggestion of a special operator in combination with an immediately 
>> following break in the action switch statement. So writing say
>>  $$$(make_unique($1, $2, $3));
>> translates into
>>  $$ = std::move(make_unique($1, $2, $3));
>>  break; 
> 
> What if I want to write:
> 
>  $$ = make_unique  ($1, $2, $3);
>  print ($$);

Then you can't use the proposed $$$, but has to use the old syntax.





Re: Automatially move from $n (was: C++11 move semantics)

2018-09-15 Thread Frank Heckenbach
Hans Åberg wrote:

> >> One idea might be to wrap the actions in inlines, and use return instead, 
> >> as C++ can recognize r-values in such situations.
> > 
> > I think we discussed this before, but this would only cover the case
> > "$$ = $N" (which is covered by the default action for N = 1 anyway).
> > 
> > More interesting are cases such as:
> > 
> >  $$ = make_unique  ($1, $2, $3);
> 
> The idea would be to write something equivalent to
>   return make_unique($1, $2, $3);
> and the Bison writes something like
>   $$ = std::move(action_k(...return make_unique($1, $2, $3);...))

I don't follow you. What is action_k, and how would that cause
moving from $1 etc.?

> Even in view of copy elision, default in C++17 [1], this would be safe, 
> because one cannot move an already moved object by mistake.

Why not?

> As the point is breaking out of the execution path, one might use your 
> suggestion of a special operator in combination with an immediately following 
> break in the action switch statement. So writing say
>   $$$(make_unique($1, $2, $3));
> translates into
>   $$ = std::move(make_unique($1, $2, $3));
>   break; 

What if I want to write:

  $$ = make_unique  ($1, $2, $3);
  print ($$);

Regards,
Frank



Re: Automatially move from $n (was: C++11 move semantics)

2018-09-15 Thread Hans Åberg


> On 15 Sep 2018, at 20:19, Frank Heckenbach  wrote:
> 
> Hans Åberg wrote:
> 
>> One idea might be to wrap the actions in inlines, and use return instead, as 
>> C++ can recognize r-values in such situations.
> 
> I think we discussed this before, but this would only cover the case
> "$$ = $N" (which is covered by the default action for N = 1 anyway).
> 
> More interesting are cases such as:
> 
>  $$ = make_unique  ($1, $2, $3);

The idea would be to write something equivalent to
  return make_unique($1, $2, $3);
and the Bison writes something like
  $$ = std::move(action_k(…return make_unique($1, $2, $3);…))

Even in view of copy elision, default in C++17 [1], this would be safe, because 
one cannot move an already moved object by mistake.

As the point is breaking out of the execution path, one might use your 
suggestion of a special operator in combination with an immediately following 
break in the action switch statement. So writing say
  $$$(make_unique($1, $2, $3));
translates into
  $$ = std::move(make_unique($1, $2, $3));
  break; 


1. https://en.cppreference.com/w/cpp/language/copy_elision





Re: Automatially move from $n (was: C++11 move semantics)

2018-09-15 Thread Frank Heckenbach
Hans Åberg wrote:

> One idea might be to wrap the actions in inlines, and use return instead, as 
> C++ can recognize r-values in such situations.

I think we discussed this before, but this would only cover the case
"$$ = $N" (which is covered by the default action for N = 1 anyway).

More interesting are cases such as:

  $$ = make_unique  ($1, $2, $3);

Regards,
Frank



Re: Automatially move from $n (was: C++11 move semantics)

2018-09-15 Thread Hans Åberg


> On 15 Sep 2018, at 19:15, Frank Heckenbach  wrote:
> 
> Akim Demaille wrote:
> 
>>> By default it's empty, so it's like before, but one can e.g. add
>>> 
>>> %define api.rhs.access {std::move}
>> 
>> I would like to have your opinion on this, a few months after
>> having practiced the idea.  It looks great, but some ideas look
>> great first, and them show some limitations.
>> 
>> Would you recommend that we really import this into Bison?
> 
> I would. My grammar file is much more readable with it, as it saves
> me multiple std::move calls in most rules.
> 
> Of course, there's a danger of using a moved-from value. When I
> introduces it, I had to check my grammars for multiple uses of the
> same value which I did to a first approximation with a regex search
> (something like "(\$[0-9]+).*\1"), then checked the few remaining
> cases manually (but my grammar rules are rather simple; most of the
> actual work is done in external functions, often just make_unique<>,
> sometimes self-written ones).
> 
> As I wrote, if Bison could detect multiple uses and warn, that would
> be great, but I didn't look into it as I didn't want to patch Bison
> itself.
> 
> Another syntax (just for the sake of example "#1" for moving, while
> keeping "$1" as is) might be an idea, but is still dangerous if one
> uses $1 after #1, so probably not worth it.
> 
> So, lacking other ideas, I'd stay with api.rhs.access, which was
> easy to implement and does the job for me. I certainly don't want to
> put std::move everywhere in my grammar. -- In fact, if I'd
> ultimately have to, I'd make make up something like "#1" and
> preprocess my grammar with sed before feeding it to Bison, to keep
> it readable. Seeing as Bison does lots of processing of the source
> anyway, this would seem overly complicated and bizarre to me.

One idea might be to wrap the actions in inlines, and use return instead, as 
C++ can recognize r-values in such situations.





Re: Automatially move from $n (was: C++11 move semantics)

2018-09-15 Thread Frank Heckenbach
Akim Demaille wrote:

> > Le 1 avr. 2018 à 16:43, Frank Heckenbach  a écrit :
> > 
> > I've now changed my grammars to use my new C++17 skeletons with
> > std::variant and move semantics. So far, it seems to work fine.
> > 
> > As expected, they now contain a lot of "std::move ($n)" expressions.
> > Even though the simple case "$$ = std::move ($1)" is now covered by
> > the default action, most are actually within expressions such as
> > "$$ = make_foo (std::move ($1), std::move ($2))" which is less than
> > perfectly readable ...
> > 
> > [...]
> > That's what I've implemented now -- except for the warning (which
> > doesn't seem possible without changes to Bison itself).
> > 
> > In fact, rather than a Boolean option, I added a define that's
> > wrapped around every $n access. (Though ATM I can't think of any
> > other function except std::move one might want to use there -- maybe
> > some fancy debugging stuff if Bison's trace mechanism isn't
> > sufficient, or whatever ...)
> > 
> > By default it's empty, so it's like before, but one can e.g. add
> > 
> >  %define api.rhs.access {std::move}
>
> I would like to have your opinion on this, a few months after
> having practiced the idea.  It looks great, but some ideas look
> great first, and them show some limitations.
> 
> Would you recommend that we really import this into Bison?

I would. My grammar file is much more readable with it, as it saves
me multiple std::move calls in most rules.

Of course, there's a danger of using a moved-from value. When I
introduces it, I had to check my grammars for multiple uses of the
same value which I did to a first approximation with a regex search
(something like "(\$[0-9]+).*\1"), then checked the few remaining
cases manually (but my grammar rules are rather simple; most of the
actual work is done in external functions, often just make_unique<>,
sometimes self-written ones).

As I wrote, if Bison could detect multiple uses and warn, that would
be great, but I didn't look into it as I didn't want to patch Bison
itself.

Another syntax (just for the sake of example "#1" for moving, while
keeping "$1" as is) might be an idea, but is still dangerous if one
uses $1 after #1, so probably not worth it.

So, lacking other ideas, I'd stay with api.rhs.access, which was
easy to implement and does the job for me. I certainly don't want to
put std::move everywhere in my grammar. -- In fact, if I'd
ultimately have to, I'd make make up something like "#1" and
preprocess my grammar with sed before feeding it to Bison, to keep
it readable. Seeing as Bison does lots of processing of the source
anyway, this would seem overly complicated and bizarre to me.

Regards,
Frank



Re: Automatially move from $n (was: C++11 move semantics)

2018-09-15 Thread Akim Demaille



> Le 1 avr. 2018 à 16:43, Frank Heckenbach  a écrit :
> 
> I've now changed my grammars to use my new C++17 skeletons with
> std::variant and move semantics. So far, it seems to work fine.
> 
> As expected, they now contain a lot of "std::move ($n)" expressions.
> Even though the simple case "$$ = std::move ($1)" is now covered by
> the default action, most are actually within expressions such as
> "$$ = make_foo (std::move ($1), std::move ($2))" which is less than
> perfectly readable ...
> 
> […]
> That's what I've implemented now -- except for the warning (which
> doesn't seem possible without changes to Bison itself).
> 
> In fact, rather than a Boolean option, I added a define that's
> wrapped around every $n access. (Though ATM I can't think of any
> other function except std::move one might want to use there -- maybe
> some fancy debugging stuff if Bison's trace mechanism isn't
> sufficient, or whatever ...)
> 
> By default it's empty, so it's like before, but one can e.g. add
> 
>  %define api.rhs.access {std::move}

Frank,

I would like to have your opinion on this, a few months after
having practiced the idea.  It looks great, but some ideas look
great first, and them show some limitations.

Would you recommend that we really import this into Bison?




Re: Automatially move from $n (was: C++11 move semantics)

2018-04-01 Thread Hans Åberg

> On 1 Apr 2018, at 23:13, Frank Heckenbach  wrote:
> 
> Hans Åberg wrote:
> 
>> An advantage with operators names is avoiding parentheses, but a
>> problem is that they are hard to search for, but here, since they
>> will always together with the $k, that should not be a problem.
>> Candidate names might be operator * & ~ + -.
> 
> As I said, I'm not really fond of (mis)using operators like that.
> Of course, you (or anyone else) might disagree and do it like that,
> Bison neither encourages nor prevents it.
> 
> My "%define" proposal is an alternative (also completely optional;
> if you don't set it, it won't do anything). I think it's a bit
> easier to use and more general -- it will apply to all types
> (including primitive types, where moving is the same as copying, so
> effectively no change for them), whereas you'd have to define the
> overloaded operator for each relevant type (and couldn't blindly
> define it for all types as it already has a meaning for some of
> them). Do you have any objections to my "%define" proposal?

It any future Bison developer that decides what to integrate. Otherwise, I 
think it is OK to be able to choose wrap around $k, but potentially unsafe to 
always have implicit std::move without pitfall checks. 





Re: Automatially move from $n (was: C++11 move semantics)

2018-04-01 Thread Frank Heckenbach
Hans Åberg wrote:

> An advantage with operators names is avoiding parentheses, but a
> problem is that they are hard to search for, but here, since they
> will always together with the $k, that should not be a problem.
> Candidate names might be operator * & ~ + -.

As I said, I'm not really fond of (mis)using operators like that.
Of course, you (or anyone else) might disagree and do it like that,
Bison neither encourages nor prevents it.

My "%define" proposal is an alternative (also completely optional;
if you don't set it, it won't do anything). I think it's a bit
easier to use and more general -- it will apply to all types
(including primitive types, where moving is the same as copying, so
effectively no change for them), whereas you'd have to define the
overloaded operator for each relevant type (and couldn't blindly
define it for all types as it already has a meaning for some of
them). Do you have any objections to my "%define" proposal?

Regards,
Frank



Re: Automatially move from $n (was: C++11 move semantics)

2018-04-01 Thread Hans Åberg

> On 1 Apr 2018, at 22:32, Frank Heckenbach  wrote:
> 
> Hans Åberg wrote:
> 
>>> If semantic_type doesn't have a "*" operator of its own, this might
>>> work (but look confusing). However, I use the variant (so I'd need
>>> this function for each alternative, which might be possible to do
>>> with templates), but some of my semantic values are (smart)
>>> pointers, so "*" is already used (and even if I could somehow
>>> override it, it would suggest dereferencing rather than moving).
>> 
>> Alternative unary operators are listed as point 3 at [1]. One can
>> overload operator&, but is more confusing than *, as it disables
>> taking the address-of.
> 
> Yeah; all existing operators have their meaning, and might apply to
> some or all alternatives one might use. C++ doesn't allow defining
> new operators (probably for good reasons), and I'm generally wary of
> overloading operators for unrelated purposes (don't already like the
> stream "<<" and ">>" too much).
> 
>>> Now, if C++ had a dedicated move operator (which would also be
>>> useful in other code) ... But (ab)using an existing operator seems
>>> confusing to me.
>> 
>> Or a shorter name.
> 
> Well, with "using std::move" it's a bit shorter (just "move ($n)"),
> but still too much clutter for my taste.

An advantage with operators names is avoiding parentheses, but a problem is 
that they are hard to search for, but here, since they will always together 
with the $k, that should not be a problem. Candidate names might be operator * 
& ~ + -.





Re: Automatially move from $n (was: C++11 move semantics)

2018-04-01 Thread Frank Heckenbach
Hans Åberg wrote:

> > If semantic_type doesn't have a "*" operator of its own, this might
> > work (but look confusing). However, I use the variant (so I'd need
> > this function for each alternative, which might be possible to do
> > with templates), but some of my semantic values are (smart)
> > pointers, so "*" is already used (and even if I could somehow
> > override it, it would suggest dereferencing rather than moving).
> 
> Alternative unary operators are listed as point 3 at [1]. One can
> overload operator&, but is more confusing than *, as it disables
> taking the address-of.

Yeah; all existing operators have their meaning, and might apply to
some or all alternatives one might use. C++ doesn't allow defining
new operators (probably for good reasons), and I'm generally wary of
overloading operators for unrelated purposes (don't already like the
stream "<<" and ">>" too much).

> > Now, if C++ had a dedicated move operator (which would also be
> > useful in other code) ... But (ab)using an existing operator seems
> > confusing to me.
> 
> Or a shorter name.

Well, with "using std::move" it's a bit shorter (just "move ($n)"),
but still too much clutter for my taste.

Regards,
Frank



Re: Automatially move from $n (was: C++11 move semantics)

2018-04-01 Thread Hans Åberg


> On 1 Apr 2018, at 21:47, Frank Heckenbach  wrote:
> 
> Hans Åberg wrote:
> 
 Maybe Bison might support some additional symbol for move action values, 
 like $$k.
>>> 
>>> I'd thought about this, but it would require changes to Bison itself
>>> (for a rather special feature, only for only target language, which
>>> can be done in the skeletons), and the user grammar files would also
>>> look differently, whereas with my way, they generally look just like
>>> they would with shared pointers, or in C, Java, etc., i.e.
>>> "$$ = make_foo ($1, $2)".
>>> 
>>> Also "$$k" would look rather similar to "$$" (probably not strictly
>>> a conflict, but maybe confusing).
>> 
>> Maybe just add to %code:
>>  semantic_type&& operator*(semantic_type& x) { return std::move(x); }
>> and use *$k, in case this operator is not needed for something else.

Should have been inlined:
  inline semantic_type&& operator*(semantic_type& x) { return std::move(x); }

> If semantic_type doesn't have a "*" operator of its own, this might
> work (but look confusing). However, I use the variant (so I'd need
> this function for each alternative, which might be possible to do
> with templates), but some of my semantic values are (smart)
> pointers, so "*" is already used (and even if I could somehow
> override it, it would suggest dereferencing rather than moving).

Alternative unary operators are listed as point 3 at [1]. One can overload 
operator&, but is more confusing than *, as it disables taking the address-of.

1. http://en.cppreference.com/w/cpp/language/operator_precedence

> Now, if C++ had a dedicated move operator (which would also be
> useful in other code) ... But (ab)using an existing operator seems
> confusing to me.

Or a shorter name.





Re: Automatially move from $n (was: C++11 move semantics)

2018-04-01 Thread Frank Heckenbach
Hans Åberg wrote:

> >> Maybe Bison might support some additional symbol for move action values, 
> >> like $$k.
> > 
> > I'd thought about this, but it would require changes to Bison itself
> > (for a rather special feature, only for only target language, which
> > can be done in the skeletons), and the user grammar files would also
> > look differently, whereas with my way, they generally look just like
> > they would with shared pointers, or in C, Java, etc., i.e.
> > "$$ = make_foo ($1, $2)".
> > 
> > Also "$$k" would look rather similar to "$$" (probably not strictly
> > a conflict, but maybe confusing).
> 
> Maybe just add to %code:
>   semantic_type&& operator*(semantic_type& x) { return std::move(x); }
> and use *$k, in case this operator is not needed for something else.

If semantic_type doesn't have a "*" operator of its own, this might
work (but look confusing). However, I use the variant (so I'd need
this function for each alternative, which might be possible to do
with templates), but some of my semantic values are (smart)
pointers, so "*" is already used (and even if I could somehow
override it, it would suggest dereferencing rather than moving).

Now, if C++ had a dedicated move operator (which would also be
useful in other code) ... But (ab)using an existing operator seems
confusing to me.

Regards,
Frank



Re: Automatially move from $n (was: C++11 move semantics)

2018-04-01 Thread Hans Åberg

> On 1 Apr 2018, at 19:23, Frank Heckenbach  wrote:
> 
> Hans Åberg wrote:
> 
>>> On 1 Apr 2018, at 16:43, Frank Heckenbach  wrote:
>>> 
>>> As expected, they now contain a lot of "std::move ($n)" expressions.
>>> Even though the simple case "$$ = std::move ($1)" is now covered by
>>> the default action, most are actually within expressions such as
>>> "$$ = make_foo (std::move ($1), std::move ($2))" which is less than
>>> perfectly readable ...
>> 
>> Maybe Bison might support some additional symbol for move action values, 
>> like $$k.
> 
> I'd thought about this, but it would require changes to Bison itself
> (for a rather special feature, only for only target language, which
> can be done in the skeletons), and the user grammar files would also
> look differently, whereas with my way, they generally look just like
> they would with shared pointers, or in C, Java, etc., i.e.
> "$$ = make_foo ($1, $2)".
> 
> Also "$$k" would look rather similar to "$$" (probably not strictly
> a conflict, but maybe confusing).

Maybe just add to %code:
  semantic_type&& operator*(semantic_type& x) { return std::move(x); }
and use *$k, in case this operator is not needed for something else.





Re: Automatially move from $n (was: C++11 move semantics)

2018-04-01 Thread Frank Heckenbach
Hans Åberg wrote:

> > On 1 Apr 2018, at 16:43, Frank Heckenbach  wrote:
> > 
> > I've now changed my grammars to use my new C++17 skeletons with
> > std::variant and move semantics. So far, it seems to work fine.
> > 
> > As expected, they now contain a lot of "std::move ($n)" expressions.
> > Even though the simple case "$$ = std::move ($1)" is now covered by
> > the default action, most are actually within expressions such as
> > "$$ = make_foo (std::move ($1), std::move ($2))" which is less than
> > perfectly readable ...
> 
> Maybe Bison might support some additional symbol for move action values, like 
> $$k.

I'd thought about this, but it would require changes to Bison itself
(for a rather special feature, only for only target language, which
can be done in the skeletons), and the user grammar files would also
look differently, whereas with my way, they generally look just like
they would with shared pointers, or in C, Java, etc., i.e.
"$$ = make_foo ($1, $2)".

Also "$$k" would look rather similar to "$$" (probably not strictly
a conflict, but maybe confusing).

Regards,
Frank



Re: Automatially move from $n (was: C++11 move semantics)

2018-04-01 Thread Hans Åberg

> On 1 Apr 2018, at 16:43, Frank Heckenbach  wrote:
> 
> I've now changed my grammars to use my new C++17 skeletons with
> std::variant and move semantics. So far, it seems to work fine.
> 
> As expected, they now contain a lot of "std::move ($n)" expressions.
> Even though the simple case "$$ = std::move ($1)" is now covered by
> the default action, most are actually within expressions such as
> "$$ = make_foo (std::move ($1), std::move ($2))" which is less than
> perfectly readable ...

Maybe Bison might support some additional symbol for move action values, like 
$$k.





Re: Automatially move from $n (was: C++11 move semantics)

2018-04-01 Thread Hans Åberg

> On 1 Apr 2018, at 16:43, Frank Heckenbach  wrote:
> 
> I've now changed my grammars to use my new C++17 skeletons with
> std::variant and move semantics. So far, it seems to work fine.
> 
> As expected, they now contain a lot of "std::move ($n)" expressions.
> Even though the simple case "$$ = std::move ($1)" is now covered by
> the default action, most are actually within expressions such as
> "$$ = make_foo (std::move ($1), std::move ($2))" which is less than
> perfectly readable ...

Maybe Bison might support some additional symbol for move action values, like 
$$k.





Automatially move from $n (was: C++11 move semantics)

2018-04-01 Thread Frank Heckenbach
I've now changed my grammars to use my new C++17 skeletons with
std::variant and move semantics. So far, it seems to work fine.

As expected, they now contain a lot of "std::move ($n)" expressions.
Even though the simple case "$$ = std::move ($1)" is now covered by
the default action, most are actually within expressions such as
"$$ = make_foo (std::move ($1), std::move ($2))" which is less than
perfectly readable ...

In the original thread, I wrote:

> Hans Åberg wrote:
>
> > >> Perhaps if it know that $1 expires, it can apply a move assignment.
> > >
> > > It could do that if $1 is mentioned only once. [...]
> >
> > I think it would be complicated, so just std::move for now.
>
> I looked into the code. Just adding std::move seems rather easy, but
> finding out if a $n is mentioned several times might be tricky on
> the m4 level, might require changes to Bison itself.
>
> And the question remains what to do then. One possibility would be
> an option auto-move or such. If not set, std::move is not inserted;
> if set it's always inserted, but Bison warns if $n is mentioned
> several times.

That's what I've implemented now -- except for the warning (which
doesn't seem possible without changes to Bison itself).

In fact, rather than a Boolean option, I added a define that's
wrapped around every $n access. (Though ATM I can't think of any
other function except std::move one might want to use there -- maybe
some fancy debugging stuff if Bison's trace mechanism isn't
sufficient, or whatever ...)

By default it's empty, so it's like before, but one can e.g. add

  %define api.rhs.access {std::move}

to always move from all $n. It's then left to the user to make sure
moving is safe. For my style of grammar that's fine -- I prefer to
do all nontrivial stuff in helper functions, so it's very rare that
any $n is mentioned several times in an action (including mid-rule
actions) at all.

If it is, one can always work around it, by moving to a temporary
first, or "un-moving" (after all, std::move doesn't actually move,
just type-cast to a moveable rvalue, so one can make it unmoveable
again with no harm done).

This seems rather lightweight, both to implement in the skeleton and
to use in the grammar file, and helps readability a lot for me.

Regards,
Frank