Perl布尔,否定(以及如何解释)?

elf*_*ess 7 perl

我是新来的.在阅读了如何询问和格式化之后,我希望这将是一个好问题.我对perl不是很熟练,但它是我最熟悉的编程语言.

我尝试将Perl应用到现实生活中,但我没有得到很好的理解 - 尤其不是来自我的妻子.我告诉她:

如果她晚上没给我3杯啤酒,那就意味着我喝了零(或没有)啤酒.

你可能已经猜到了,没有太大的成功.:(

事实上,现在.来自perlop:

一元"!" 执行逻辑否定,即"不".

语言,有什么boolean类型(什么只有两个"值")是可以的:

如果它不是一个值 - > 必须是另一个值.

很自然地:

!true  -> false
!false -> true
Run Code Online (Sandbox Code Playgroud)

但Perl不具有boolean变量-只有一个truth system,whrere一切都不是0,'0' undef,''为TRUE.当将逻辑否定应用于非逻辑值(例如数字)时出现问题.

例如,如果某个数字不是3,那意味着它是零或空,而不是现实生活意义,如果某事物不是3,则意味着它可以是3以外的任何数字(例如也为零).

那么下一个代码:

use 5.014;
use Strictures;

my $not_3beers = !3;

say defined($not_3beers) ? "defined, value>$not_3beers<" : "undefined";
say $not_3beers ? "TRUE" : "FALSE";

my $not_4beers = !4;
printf qq{What is not 3 nor 4 mean: They're same value: %d!\n}, $not_3beers if( $not_3beers == $not_4beers );
say qq(What is not 3 nor 4 mean: @{[ $not_3beers ? "some bears" : "no bears" ]}!) if( $not_3beers eq $not_4beers );

say ' $not_3beers>',  $not_3beers, "<";
say '-$not_3beers>', -$not_3beers, "<";
say '+$not_3beers>', -$not_3beers, "<";
Run Code Online (Sandbox Code Playgroud)

打印:

defined, value><
FALSE
What is not 3 nor 4 mean: They're same value: 0!
What is not 3 nor 4 mean: no bears!
 $not_3beers><
-$not_3beers>0<
+$not_3beers>0<
Run Code Online (Sandbox Code Playgroud)

此外:

perl -E 'say !!4'
Run Code Online (Sandbox Code Playgroud)

什么不是4 IS 1,而不是4!

以上与妻子的陈述是"假的"(意思是0):),但是真的试着教我的儿子 Perl和他,过了一会儿,问我的妻子:为什么,如果有什么不是3意味着它是0?.

所以问题是:

  • 怎么向我的儿子解释这个
  • 为什么perl有这个设计,所以为什么!0每次都是1
  • 这里有什么东西"背后"需要!0的不是任何随机数,而是0.
  • 正如我已经说过的,我不太了解其他语言 - 在每种语言中都是如此!3 == 0

amo*_*mon 11

我认为你在很大程度上依赖于否定,而对Perl booleans的意思却太少了.

历史/实施视角

什么是真理?检测到更高的电压即x伏特.

在更高的抽象级别:如果此位置位.

比特序列的抽象可以被认为是整数.这个整数是假的吗?是的,如果没有设置位,即整数为零.

面向硬件的语言可能会使用这个真理定义,例如C,以及包含Perl的所有C后代.

否定0可以是按位否定 - 所有位都被翻转为1- ,或者我们只将最后一位设置为1.结果将通常被解码为整数-11分别,但后者是更节能.

务实的观点

当我们处理计数时,很容易想到所有数字,但为零是真的:

my $wordcount = ...;

if ($wordcount) {
  say "We found $wordcount words";
} else {
  say "There were no words";
}
Run Code Online (Sandbox Code Playgroud)

要么

say "The array is empty" unless @array;  # notice scalar context
Run Code Online (Sandbox Code Playgroud)

像Perl这样的实用语言可能会认为零是错误的.

数学视角

任何数字都没有理由是错误的,每个数字都是明确定义的实体.真理或虚假仅通过谓词表达,表达可以是真或假.只有这个真值才能被否定.例如

¬(x ? y) where x = 2, y = 3
Run Code Online (Sandbox Code Playgroud)

是假的.许多具有强大数学基础的语言不会考虑任何错误,而是一种特殊的虚假价值.在Lisps中,'()或者nil通常是假的,但0通常都是真的.也就是说,如果值不是零,则该值仅为真!

在这种数学语言中,!3 == 0很可能是类型错误.

回复:啤酒

啤酒很好吃.任何数量的啤酒都是好的,只要你有一个:

my $beers = ...;

if (not $beers) {
  say "Another one!";
} else {
  say "Aaah, this is good.";
}
Run Code Online (Sandbox Code Playgroud)

啤酒计数变量的升级只是告诉我们你是否有啤酒.考虑!!成为一个boolification运营商:

my $enough_beer = !! $beers;
Run Code Online (Sandbox Code Playgroud)

boolification不涉及确切的数量.但也许任何数量≥3都是好的.然后:

my $enough_beer = ($beers >= 3);
Run Code Online (Sandbox Code Playgroud)

否定啤酒是不够的:

my $not_enough_beer = not($beers >= 3);
Run Code Online (Sandbox Code Playgroud)

要么

my $not_enough_beer = not $beers;

fetch_beer() if $not_enough_beer;
Run Code Online (Sandbox Code Playgroud)

Perl标量并不代表整个事物的世界.特别是,not 3不是所有不是三个实体的集合.表达式3是真正的价值吗?是.因此,not 3是一个虚假的价值.

建议的4 == not 3真实行为可能是不可取的:4并且"所有不是三的东西"都不相等,这四种只是众多不是三种东西中的一种.我们应该写得正确:

4 != 3    # four is not equal to three
Run Code Online (Sandbox Code Playgroud)

要么

not( 4 == 3 )   # the same
Run Code Online (Sandbox Code Playgroud)

它可以帮助想!not作为逻辑否定-的,但不能作为除外.

怎么教

可能值得引入数学谓词:表达式可以是真或假.如果我们只通过明确的测试"创造"真实性,例如length($str) > 0,那么你的问题就不会出现.我们可以命名结果:my $predicate = (1 < 2)但我们可以决定永远不要打印出来,而是:print $predicate ? "True" : "False".这避免了考虑假的特殊表示的问题.

直接考虑值为真/假将只是一个快捷方式,例如foo if $x可以被认为是快捷方式

foo if defined $x and length($x) > 0 and $x != 0;
Run Code Online (Sandbox Code Playgroud)

Perl就是关于捷径的.

教这些快捷方式,以及perl的各种上下文以及它们出现的位置(数字/字符串/布尔运算符)可能会有所帮助.

  • 列表上下文
    • 偶数大小的列表上下文
  • 标量上下文
    • 数字语境
    • 字串上下文
    • 布尔上下文
  • 虚空背景


DVK*_*DVK 8

  • 正如我已经说过的,我不太了解其他语言 - 每种语言都是!3 == 0?

  • 怎么向我的儿子解释这个
  • 非常简单.!3意思是"与某些非虚假价值相反,这当然是错误的".这被称为"上下文" - 在由否定运算符强加的布尔上下文中,"3"不是数字,它是真/假的陈述.

    结果也并不是一个"零",而只是东西是虚假的Perl方便代表性-这变成如果在数值上下文中使用的零(但如果在字符串上下文中使用空字符串-看到的区别0 + !3!3 . "a")

    布尔上下文只是一种特殊的标量上下文,不会执行到字符串或数字的转换.(perldoc perldata)


  • 为什么perl有这个设计,所以为什么!0每次都是1

  • 这里有什么东西"背后"需要什么!0不是任何随机数,而是0.
  • 除了简单的实施之外没什么.产生"1"比随机数更容易.

  • 如果你问一个不同的问题"为什么它是1而不是原来的#被否定得到0",答案很简单 - 当Perl解释器得到否定零时,它不再知道/记得零是"!3"的结果,而不是导致值为零/假的其他表达式.