SYAM さん、ありがとうございます。ずいぶん前から3人の発言の根本的な部分に何かしらのズレがあるなぁと感じていたのですが、SYAM さんの解説のおかげで、ようやく何がすれ違っているのか理解する事が出来ました。if の条件式における and, or の動作内容にお互い違う認識を持っていたようです。
if (1 == 1) and 1
共通する認識:
if の条件式の結果が 0 以外なら真、0 なら偽。
私の and の動作の認識(真の値は「ここでは」-1 とする):
(1 == 1) を実行し真 (-1) を返す。
その結果 (-1) と 1 をビット毎に AND し、その結果 (1) を返す。
if の条件式の結果 (1) が 0 以外なので真。よって本文は実行される。
ANTARES さんの and の動作の認識(真の値は「ここでは」-1 とする):
(1 == 1) を実行し真 (-1) を返す。
その結果 (-1) と 1 をビット毎に AND し、
その結果 (1) が「0 でないなら真 (-1) を、0 なら偽 (0) を返す」。ここでは真 (-1) が返る。
if の条件式の結果 (-1) が 0 以外なので真。よって本文は実行される。
つまり、ANTARES さんの考えでは、and は「整数型の値を受け取り、ビット毎に AND して、その『結果に応じた真偽値』を返す演算子」であるが、私の方では、and は「整数型の値を受け取り、ビット毎に AND して、その『結果である整数値』を返す演算子」であると想定しているという事です。プログラムに書き落とすとより分かりやすいので、以下にそのスクリプトを書いておきます。
(余談ですが、== や <, >= などの比較演算子は、2つの整数・実数・文字列を受け取り、比較した結果に応じた真偽値を返します。これに関しては誰もが同様に考えている動作だと思います。)
#module ANTARESS_AND
#defcfunc and int lhs, int rhs ; それぞれ、& の左辺と右辺
if lhs & rhs: return -1 ; ビット AND して真なら -1 を
return 0 ; 偽なら 0 を返す
#global
; ANTARES さんの and は論理演算的動作
#module SHINKUNS_AND
#defcfunc and int lhs, int rhs
return lhs & rhs ; ビット AND したものを返す
#global
; 私の and はビット演算
こういう動作を想定した上で、次のプログラムの動作を追いかけるとこうなります。
if (1 == 1) and 1 and (-1 & 2)
私の and の動作の場合(真の値は「ここでは」-1 とする):
(1 == 1) を実行し真 (-1) を返す。
その結果 (-1) と 1 をビット毎に AND し、その結果 (1) を返す。
その結果 (1) と (-1 & 2) の結果 (2) をビット毎に AND し、その結果 (0) を返す。
if の条件式の結果 (0) が 0 なので偽。よって実行されない。
ANTARES さんの and の動作の認識(真の値は「ここでは」-1 とする):
(1 == 1) を実行し真 (-1) を返す。
その結果 (-1) と 1 をビット毎に AND し、その結果 (1) が 0 でないので真 (-1) を返す。
その結果 (-1) と (-1 & 2) の結果 (2) をビット毎に AND し、
その結果 (2) が 0 でないので真 (-1) を返す。
if の条件式の結果 (-1) が 0 以外なので真。よって実行される。※1
このような違いが出て来ます。
私が NO.27587 で、ANTARES さんの方法では問題は解決しないのでは?と言ったのは、その時点において、and の動作が上述の私の考えていた動作であると思っていたからです。そしてそれは、皆が共有しているものだと思っていました。だから、どうして真の値を -1 にする「だけ」で問題が解決するのか疑問だったわけです。私の and は本当に単なるビット演算で真偽値を返さないので。私が始めから ANTARES さんの and の動作を想定していたなら、私もその方法に納得していたと思います。ここにお互いの認識のズレがあったのですね。
HSP における and の実装が実際の所どうなっているのか詳細は知りませんが、早い内にこの問題を修正して欲しいです。本当に真の値を -1 にするだけでいいなら、明日にでも修正してもらいたいですね。
ちなみに私は、次のような動作になるよう修正してもらえたらと当初から考えていました。
#module
#defcfunc and int lhs, int rhs
return (lhs != 0) & (rhs != 0)
#global
; テスト
if 1 and 0: mes "偽" ; これで上の and が呼び出されると思いねぇ
if 1 and 1: mes "真" ; lhs には左辺、rhs には右辺が代入される
stick key
if (key & 1) and (x == 1): ... ; もちろん、& は通常のビット AND として利用できる
※1
> Windowsへの移植版らしきN88BASICで試したところ、ifが-1だけを真としていました。
私も N88互換BASIC for Windows95 というシミュレーションソフトで動作テストしていたのですが、このソフトが -1 だけを真としているのは、(私の考える)ANTARES さんの方法での比較演算子および AND, OR では、if 条件式の最終結果は真偽値にしかならないという前提があったからだろうと思います。
ただ、実際は、
if a then ...
とか書けちゃうので、その前提はおかしいのですが…。
私が BASIC は比較演算を使わない条件は許さないとか偽になるとかって結論付けたのも、この辺の挙動をみたからでした。
if -1 then ...
をテストせず
if 1 then ...
などだけで動作テストしていたので、比較演算や論理演算しない条件式は動かないと思っていたのです。
------------------------------------------------------------------------------------
余談です。自らの保身のために、皆さんが疑問を持たれた
> 比較が正しい時(1 == 1 とか)の真を -1 にするだけじゃなく、
> 条件式の結果が -1(真)の時だけ if が成立する(if -1: ... で成立)ようにする
この点について、自分でフォローしておきます。
まず第一に、私と ANTARES さんでは & に関する動作の認識が違っていました。それは既に述べた通りです。ですから、ANTARES さんの方法では何の解決にもならないと思っていました。ですが、根拠もなくそんな事を言う人だとは到底思えないので、どこかしら自分の解釈に間違いがあるのだろうと思っていたのです。(その時は =, !, <, >, <=, >= の比較演算子が -1, 0 という真偽値を返すもので、&, | はビット演算、if はその結果が 0 以外の時は真とみなすように想定していました。)
その間違いを見つけようと努力した結果が、if の結果が -1 の時のみ真とみなすという風に修正して今回疑問視されたアレで、これは言語的一貫性が以前よりあるものでした。
言語的一貫性とは、これまで何度も述べてますが
if x : ...
これでif が真になる x については
if x and y : ...
この例で y が真のとき、全体としての結果も必ず真になるというものです。現状の HSP では必ずしもこうなるとは限りません。
ここで、if の条件式の結果が -1 の時だけ真とみなされるようになれば、話がチョット違ってきます。これまで 0 以外で真だった物が -1 に固定された訳ですから、1 とか 2 とかでは偽になります。
if -1 : mes "真"
if 0 : mes "偽"
if 1 : mes "偽"
ここで、ビット AND の結果が -1 になる場合の & の 2 つの引数はどういう状況かというと…
if -1 & -1 : mes "真"
両方とも -1 でなければなりません。これなら、& がビット AND の動作のままでも、(使いづらいですが)一貫性が生まれます。そのため、
if (key & 1) : ... ; 常に偽なので意味がない
if (key & -1) : ... ; そもそも & する必要がない
if (key & 1) & (x == 2) : ... ; やはり常に偽なので意味がない
このように書く事は誤りとなるため、当然サンプルプログラムでこのように解説される事はなくなるでしょうし、条件の中でビット演算している場合(この例なら (key & 1) とか)、比較演算しないといけないという認識が生まれるはずです。全体として比較演算を用いる事が当然となれば、条件式中の途中結果に出てくる値は真偽値だけになるので、真の値は -1 だろうが 1 だろうが関係なくなります。
ただし、全体としては偽になるはずなのに or していった結果たまたま -1 になって真とされてしまう事があるため、この方法は完全ではありません。これは真の値である -1 をその他の値に変えてもどこかしらで同様の問題に遭遇します。(そういう意味で真の値が -1 だろうが 1 だろうが関係なかったとも言えます。)
(if の条件式中における)ビット AND 動作の解釈に違いがあると気付いていなかったあの時点では、かなり強引な考え方でありましたが、少なくともより優れた方法であったと思ったのでした。
まぁ、今冷静になって考えてみれば、その言語的一貫性という考え方は不自然だと言っていた方がこういう提案するはずもないのですが…。(^^;
------------------------------------------------------------------------------------
色々と説明が下手で理解に苦しみ、時には不愉快な想いをさせてしまったかもしれません。(特に ANTARES さん。)ですが、私は別に敵対したかったわけではありません。ANTARES さんの考え方は新鮮で、しかし、どこかしら腑に落ちない点があったので、それが何なのか知りたかっただけなのです。& 動作の認識の違いにさえ話が進めば良かったのですが、そこに行き着くまでに強制的に話を切られてしまったのが残念です。
一応納得出来ましたが、ANTARES さん本人がこういう考え方だったのかどうかは結局分からないままなんですよね。YES, NO だけでも回答があると嬉しいのですが…。
------------------------------------------------------------------------------------
なんかもう、完全にスレ違いになってますね。皆さん本当に申し訳ないです。毎度の長文もすみません。
SYAM さん、的確なフォローありがとうございました。たぶん SYAM さんがフォローに入ってくれなかったら、単なるケンカにしかならなかったです。いや、ホント。
もっとコミュニケートの勉強すべきですね…。
最後に。HSP が誰にとってもより扱いやすく分かりやすい言語になりますように。