다음을 고려하세요:
if(a == b or c)
대부분의 언어에서 다음과 같이 작성해야합니다.
if(a == b or a == c)
약간 번거롭고 정보를 반복합니다.
위의 샘플 구문이 약간 복잡하다는 것을 알고 있지만 아이디어를 전달하는 더 좋은 방법이 있다고 확신합니다.
더 많은 언어가 제공하지 않는 이유는 무엇입니까? 성능이나 구문 문제가 있습니까?
다음을 고려하세요:
if(a == b or c)
대부분의 언어에서 다음과 같이 작성해야합니다.
if(a == b or a == c)
약간 번거롭고 정보를 반복합니다.
위의 샘플 구문이 약간 복잡하다는 것을 알고 있지만 아이디어를 전달하는 더 좋은 방법이 있다고 확신합니다.
더 많은 언어가 제공하지 않는 이유는 무엇입니까? 성능이나 구문 문제가 있습니까?
답변:
구문 문제는 구문이 필요하다는 것입니다.
귀하의 언어가 어떤 구문을 가지고 있든지, 언어를 사용하는 사람들은 그 언어를 배워야합니다. 그렇지 않으면 코드를보고 코드의 기능을 모를 위험이 있습니다. 따라서 언어에 많은 경우를 깔끔하게 처리하는 간단한 구문이있는 경우 일반적으로 좋은 것으로 간주됩니다.
특정 예에서, 중위 연산자 (두 개의 인수를 사용하지만 작성된 함수)를 가져 와서 Argument1 Operator Argument2
여러 인수로 확장하려고합니다. infix 연산자의 전체 요점은 연산자가 2 개의 인수 사이에 올바르게 놓여 있기 때문에 매우 깨끗하게 작동하지 않습니다. 로 확장 (Argument1 Operator Argument2 MagicallyClearSymbol Argument3...)
해도에 많은 명확성이 추가되지 않는 것 같습니다 Equals(Arg1,Arg2,...)
. Infix는 일반적으로 사람들이 잘 알고있는 수학적 규약을 에뮬레이션하는 데 사용되는데, 이는 대체 구문에는 해당되지 않습니다.
파서는 구문 분석 속도에 약간의 영향을 줄 수있는 다른 생산 규칙 또는 2 개의 문법을 처리해야한다는 것 외에는 아이디어와 관련된 특정 성능 문제가 없습니다. 이는 해석되거나 JIT 컴파일 된 언어에 약간의 차이를 만들 수 있지만 큰 차이는 없습니다.
이 아이디어의 더 큰 문제 는 언어에서 특별한 경우 를 많이 만드는 것이 나쁜 아이디어 인 경향이 있다는 것 입니다.
.
있습니다. 그래서 그들은로 쓰여질 것 arg1 op (arg2, arg3)
입니다. 정확히 아름답지는 않지만 그 언어의 맥락에서 어떤 곳에서는 필요했습니다.
a == b or c
다른 사람이 원하는 동안 모든 사람이 필요한 것은 아닙니다 a == b or c but not d
. 유틸리티 기능 / 라이브러리가 구출되는 IMO입니다.
f().Equals(a,b,c)
; (var temp=f(); temp.Equals(a)||temp.Equals(b)||temp.Equals(c))
구문이 완벽하다고 평가 될 수 있지만, 그렇게 평가 int[] arr = {a,b,c}; f().Equals(arr);
되지 않으면, 특히 각 호출에 대해 새 배열을 작성해야하는 경우에는 좋지 않습니다.
문제가 아니기 때문에 해결하면 기본적으로 이점이 없지만 구현하면 비용이 들지 않습니다.
기존의 범위 기반 기능과 실제로 모든 언어가 제공하는 기능 a == b || a == c
은 자르지 않는 크기로 확장되는 경우이 상황에서 완벽하게 작동 할 수 있습니다 .
in_array($a, [$b, $c, $d, $e, $f])
. : P
일부 언어에는 그러한 기능이 있습니다. 예를 들어 Perl6에서는 Junctions 를 사용할 수 있습니다. Junctions 는 두 값의 "중첩"입니다.
if $a == any($b, $c) {
say "yes";
}
# syntactic sugar for the above
if $a == $b | $c {
say "yes";
}
정션을 사용하면 스칼라 연산이 일부 언어의 컬렉션에 분산되는 방식과 유사하게 데이터 집합에 대한 연산을 매우 간결하게 표현할 수 있습니다. 예를 들어 Python을 numpy와 함께 사용하면 비교가 모든 값에 분산 될 수 있습니다.
import numpy as np
2 == np.array([1, 2, 3])
#=> np.array([False, True, False], dtype=np.bool)
(2 == np.array([1, 2, 3])).any()
#=> True
그러나 이것은 선택된 기본 유형에 대해서만 작동합니다.
접합부가 왜 문제가됩니까? 정션에 대한 작업은 포함 된 값으로 분산되므로 정션 오브젝트 자체는 메소드 호출을위한 프록시처럼 작동합니다. 오리 입력 외에는 몇 가지 유형 시스템 만 처리 할 수 있습니다.
이러한 정션이 비교 연산자 주위의 특수 구문 으로 만 허용되면 유형 시스템 문제를 피할 수 있습니다 . 그러나이 경우에는 너무 제한되어 있으므로 제정신의 언어에 추가 될만큼 충분한 가치를 추가하지 못합니다. 동일한 동작이 set 연산을 사용하여 표현되거나 모든 비교를 수동으로 철자 할 수 있으며, 이미 완벽하게 훌륭한 솔루션이있는 경우 대부분의 언어는 중복 구문 추가를 믿지 않습니다.
2 in [1, 2, 3]
. 반면에, numpy에 .all()
무언가 가 있다면 , 동등한 일반 파이썬은 간결하지 않습니다.
==
연산자를 사용 <
했지만 대신 사용할 수도 있습니다. in
현재 위치는 어디 입니까? 접합에 대한 작업은 모든 회원을 통해 배포하기 때문에 접합은, 세트 회원 테스트보다 더 일반적이다 - (x|y).foo
이다 x.foo|y.foo
, 접합 마침내 하나의 값으로 붕괴 될 때까지. 제공된 NumPy 코드는 기본 유형을 가정 할 때 Perl6 접합의 정확히 동일하지만 더 자세한 변환을 보여줍니다.
일부 (인기있는) 언어에서 ==
연산자는 전 이적이지 않습니다. 자바 스크립트의 예를 들어 0
모두 동일 ''
하고 '0'
다음 만 ''
하고 '0'
서로 동일하지 않습니다. PHP에서 그러한 단점이 더 많습니다.
그것은 그것이 의미하는 a == b == c
그것으로 해석인지에 따라 다른 결과를 얻을 수 있기 때문에, 다른 모호성을 추가 (a == b) & (a == c)
하거나 (a == b) & (a == c) & (b == c)
.
대부분의 언어에서, In
함수 를 작성함으로써 사소한 것을 달성 할 수 있어야하는데 왜 실제 언어의 일부로 만드는가?
예를 들어 Linq는 Contains()
입니다.
자, 모든 여러분을 위해 C #에서 구현 한 것이 있습니다.
public static bool In<T>(this T obj, params T[] values)
{
for(int i=0; i < values.Length; i++)
{
if (object.Equals(obj, values[i]))
return true;
}
return false;
}
a == b || a == c
여러 번 쓰는 것을 본다면 아마 그럴 시간입니다.equals_any(a, {b, c})
if (a > (b or c))
and와 같은 것을 다루기 위해 쉽게 확장되지 않습니다 if (a mod (b or c) == 2)
.
i
변수 가 없습니다 . 당신이 긴 하루를 했어 후 :) 모두를 가하고 있기 때문에 전체가 기록 될 것으로 보인다 return true
및 return false
루프 내부의 것은 여기가 최초의 반복을 넘어 그것을 만들 것입니다 방법이 없습니다 것을 의미합니다. 첫 번째와 만 비교하고 value
있습니다. 그건 그렇고, Any
return values.Any(value => Object.Equals(obj, value));
"if (a == b 또는 c)"는 대부분의 언어에서 작동합니다. a == b 인 경우 또는 c가 음수, 널 또는 0이 아닌 경우.
그것이 장황하다는 불만은 요점을 놓치고 있습니다. 조건부로 12 가지 물건을 쌓아서는 안됩니다. 하나의 값을 임의의 수의 다른 값과 비교해야하는 경우 서브 루틴을 빌드하십시오.
c
부울로 평가 되면 거의 모든 언어가 처리 할 수 있습니다 a == b || c
:)
if(a == b or c)
. 휴식을 취해야한다고 생각합니다 ... : P
if (a == b or c)
있는지 확인하는 의사 코드이다 a
IS 같 b
거나 a
같은지가 c
. c
0이 아닌 것을 확인하는 것은 아닙니다.
일반적으로 구문을 최소한으로 유지하고 언어 자체에서 이러한 구문을 정의 할 수 있습니다.
예를 들어, Haskell에서는 두 개 이상의 인수가있는 함수를 백틱을 사용하여 중위 연산자로 변환 할 수 있습니다. 이것은 당신이 쓸 수 있습니다 :
if a `elem` [b, c] then ... else ...
여기서 elem
두 개의 인수 (값과 값 목록)를 취하는 일반 함수이며 첫 번째 요소가 두 번째 요소인지 확인합니다.
and
대신에 사용하려면 or
어떻게합니까? Haskell에서는 컴파일러 공급 업체가 새로운 기능을 구현할 때까지 기다리지 않고 다음을 사용할 수 있습니다.
if all (== a) [b, c] then ... else ...
일부 언어는이를 어느 정도 제공합니다.
어쩌면 구체적인 예는 아니지만 파이썬 라인을 예로 들어 보겠습니다.
def minmax(min, max):
def answer(value):
return max > value > min
return answer
inbounds = minmax(5, 15)
inbounds(7) ##returns True
inbounds(3) ##returns False
inbounds(18) ##returns False
따라서 일부 언어는 올바르게 표현하기 만하면 여러 비교가 가능합니다.
불행히도, 당신이 비교를 위해 기대했던 것처럼 그것은 작동하지 않습니다.
>>> def foo(a, b):
... def answer(value):
... return value == a or b
... return answer
...
>>> tester = foo(2, 4)
>>> tester(3)
4
>>> tester(2)
True
>>> tester(4)
4
>>>
" True 또는 4를 반환 한다는 것은 무슨 뜻 입니까?" -당신이 후 고용
이 경우 적어도 Python을 사용하는 한 가지 해결책은 약간 다르게 사용하는 것입니다.
>>> def bar(a, b):
... def ans(val):
... return val == a or val == b
... return ans
...
>>> this = bar(4, 10)
>>> this(5)
False
>>> this(4)
True
>>> this(10)
True
>>> this(9)
False
>>>
편집 : 다음은 파이썬에서도 비슷한 일을 할 것입니다 ...
>>> def bar(a, b):
... def answer(val):
... return val in (a, b)
... return answer
...
>>> this = bar(3, 5)
>>> this(3)
True
>>> this(4)
False
>>> this(5)
True
>>>
당신이 사용하고있는 중 언어 그래서, 당신이 있다고하지 않을 수 없다 먼저 논리가 실제로 어떻게 작동하는지에 대해 자세히 살펴해야한다 그냥 그것을 할. 일반적으로 언어에 대해 실제로 말하는 것이 무엇인지 아는 것만으로도 문제가되지 않습니다.
APL 스타일 언어를 사용하면 한 번의 작업으로 스칼라를 벡터의 각 요소와 비교할 수 있습니다. 부울 벡터가 생성됩니다. 예를 들어, 나는 최소한의 기능을 갖춘 apl 계산기 인 잉카 ( 온라인 통역사 )를 부끄럽게 홍보하고 싶습니다 .
a<5
5
b<4
4
c<5
5
a=b c
0 1
이 값을 단일 값으로 줄이려면 포괄적이거나 0이 아닌 값을 합산하여 확인하면됩니다.
0!+/a=b c
1
c<6
6
0!+/a=b c
0
다른 답변에서 알 수 있듯이 문제는 구문입니다. 어쨌든 배열 패러다임을 배우는 데 드는 막대한 비용으로 구문 솔루션 이 발견되었습니다.