Development Tip

이상한 언어 기능

yourdevel 2020. 9. 27. 14:10
반응형

이상한 언어 기능


귀하의 의견으로는 가장 놀랍고, 이상하고, 이상하거나, 정말로 "WTF"언어 기능이 무엇이라고 생각하십니까?

답변 당 하나의 기능 만 사용하세요.


C에서 배열은 다음과 같이 인덱싱 될 수 있습니다.

a[10]

매우 일반적입니다.

그러나 덜 알려진 형식 (실제로 작동합니다!)은 다음과 같습니다.

10[a]

이는 위와 같은 의미입니다.


JavaScript에서 :

 '5' + 3 gives '53'

이므로

 '5' - 3 gives 2

JavaScript에서 다음 구문

return
{
    id : 1234,
    title : 'Tony the Pony'
};

복귀 undefined 인한 후 바꿈에 부적절한 암시 세미콜론 삽입에 구문 오류이다 return. 다음은 예상대로 작동합니다.

return {
    id : 1234,
    title : 'Tony the Pony'
};

더 나쁜 것은 이것도 작동한다는 것입니다 (적어도 Chrome에서는).

return /*
*/{
    id : 1234,
    title : 'Tony the Pony'
};

다음은 구문 오류를 일으키지 않고 조용히 실패하는 동일한 문제의 변형입니다.

return
    2 + 2;

자바 스크립트 진리표 :

''        ==   '0'           // false
0         ==   ''            // true
0         ==   '0'           // true
false     ==   'false'       // false
false     ==   '0'           // true
false     ==   undefined     // false
false     ==   null          // false
null      ==   undefined     // true
" \t\r\n" ==   0             // true

출처 : Doug Crockford


C 및 C ++의 Trigraphs.

int main() {
   printf("LOL??!");
}

LOL|삼중 문자 ??!가로 변환 되기 때문에 인쇄 됩니다 |.


자바의 자동 복싱 및 정수 캐시로 재미 :

Integer foo = 1000;
Integer bar = 1000;

foo <= bar; // true
foo >= bar; // true
foo == bar; // false

//However, if the values of foo and bar are between 127 and -128 (inclusive)
//the behaviour changes:

Integer foo = 42;
Integer bar = 42;

foo <= bar; // true
foo >= bar; // true
foo == bar; // true

설명

Java 소스 코드를 빠르게 살펴보면 다음과 같은 결과가 나타납니다.

/**
 * Returns a <tt>Integer</tt> instance representing the specified
 * <tt>int</tt> value.
 * If a new <tt>Integer</tt> instance is not required, this method
 * should generally be used in preference to the constructor
 * {@link #Integer(int)}, as this method is likely to yield
 * significantly better space and time performance by caching
 * frequently requested values.
 *
 * @param  i an <code>int</code> value.
 * @return a <tt>Integer</tt> instance representing <tt>i</tt>.
 * @since  1.5
 */
public static Integer valueOf(int i) {
    if (i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}

참고 : 속성에서 설정하지 않는 한 IntegerCache.high기본값은 127입니다.

자동 복싱에서 발생하는 것은 명시 적으로 생성되지 않는 한 캐시에서 검색된 동일한 정수 객체를 foo와 bar 모두에 적용하는 것입니다. 예를 들어 foo = new Integer(42)참조 동등성을 비교할 때 거짓이 아니라 참이됩니다. Integer 값을 비교하는 적절한 방법은.equals;


Neil Fraser (페이지 끝 부분 참조)를 인용 하여

try {
    return true;
} finally {
    return false;
}

(Java에서는 동작이 JavaScript와 Python에서 분명히 동일합니다.) 결과는 독자에게 연습으로 남겨집니다.

편집 됨 : 주제에 관한 한 다음 사항도 고려하십시오.

try {
    throw new AssertionError();
} finally {
    return false;
}

APL (모두 제외)은 한 줄에 모든 프로그램을 작성할 수있는 기능입니다.

예 : Conway의 Game of Life in one line in APL :

대체 텍스트 http://catpad.net/michael/APLLife.gif

그 라인이 WTF가 아니라면 아무것도 아닙니다!

그리고 여기에 비디오가 있습니다


C ++ 템플릿을 사용할 수있는 이상한 점 은 템플릿을 사용하여 "그린"모양의 영역을 계산하는 "다차원 아날로그 리터럴" 에서 가장 잘 설명됩니다 . 다음 코드는 3x3 직사각형에 유효한 C ++입니다.

#include"analogliterals.hpp"
using namespace analog_literals::symbols;

          unsigned int c = ( o-----o
                             |     !
                             !     !
                             !     !
                             o-----o ).area;

또는 3D 큐브가있는 다른 예 :

  assert( ( o-------------o
            |L             \
            | L             \
            |  L             \
            |   o-------------o
            |   !             !
            !   !             !
            o   |             !
             L  |             !
              L |             !
               L|             !
                o-------------o ).volume == ( o-------------o
                                              |             !
                                              !             !
                                              !             !
                                              o-------------o ).area * int(I-------------I) );

Perl의 많은 내장 변수 :

  • $#코멘트가 아닙니다 !
  • $0, $$,와 $?- 그냥 같은 이름으로 쉘 변수와 같은
  • , $&$'— 이상한 일치 변수
  • $"$,— 목록 및 출력 필드 구분자를위한 이상한 변수
  • $!errno숫자와 같지만 strerror(errno)문자열
  • $_- 스텔스 변수는 항상 사용 및 본 적이
  • $#_ — 마지막 서브 루틴 인수의 인덱스 번호 ... 어쩌면
  • @_ — 현재 함수의 (비) 이름 ... 어쩌면
  • $@ — 마지막으로 발생한 예외
  • %:: — 기호 테이블
  • $:, $^, $~, $-,와 $=- 뭔가 출력 형식으로해야 할 일
  • $.그리고 $%— 입력 라인 번호, 출력 페이지 번호
  • $/$\— 입력 및 출력 레코드 구분자
  • $| — 출력 버퍼링 컨트롤러
  • $[— 어레이 기반을 0 기반에서 1 기반으로 42 기반으로 변경 : WHEEE!
  • $}전혀, 이상하게도 충분합니다!
  • $<, $>, $(, $)- 진짜하고 효과적인 UID 및 GID
  • @ISA — 현재 패키지의 직접 수퍼 클래스 이름
  • $^T — 스크립트 시작 시간 (epoch 초)
  • $^O — 현재 운영 체제 이름
  • $^V — 이것은 Perl의 버전

그 출처가 훨씬 더 많습니다. 여기 에서 전체 목록을 읽어보십시오 .


PHP의 문자열 숫자 값 처리 . 자세한 내용 은 다른 질문에 대한 이전 답변을 참조하십시오 .

"01a4" != "001a4"

문자 수가 다른 두 개의 문자열이있는 경우 동일한 것으로 간주 할 수 없습니다. 선행 0은 숫자가 아닌 문자열이기 때문에 중요합니다.

"01e4" == "001e4"

PHP는 문자열을 좋아하지 않습니다. 당신의 가치를 숫자로 취급하기 위해 찾을 수있는 변명을 찾고 있습니다. 해당 문자열의 16 진수 문자를 약간 변경하면 갑자기 PHP가 이러한 문자가 더 이상 문자열이 아니라고 결정하고 과학적 표기법의 숫자이며 (PHP는 인용 부호를 사용해도 상관 없음) 숫자에 선행 0이 무시되기 때문에 동등합니다. 이 점을 강화하기 위해 PHP도 "01e4" == "10000"동일한 값을 가진 숫자이기 때문에 참으로 평가된다는 것을 알 수 있습니다. 이것은 문서화 된 행동이며, 그다지 현명하지 않습니다.


예약어를 없애려고 시도한 모든 언어 (예 : PL / I)에 대해 투표합시다.

다음과 같은 재미있는 표현을 합법적으로 쓸 수있는 곳은 어디입니까?

IF IF THEN THEN = ELSE ELSE ELSE = THEN

( IF, THEN, ELSE변수 이름이다)

또는

IF IF THEN THEN ELSE ELSE

( IF변수이고, THENELSE서브 루틴)


자바 스크립트 8 진수 변환 '기능'은 알아두면 좋은 것입니다.

parseInt('06') // 6
parseInt('07') // 7
parseInt('08') // 0
parseInt('09') // 0
parseInt('10') // 10

자세한 내용은 여기를 참조 하세요 .


C에서 더프의 장치!

C에서는 do / while을 switch 문과 인터레이스 할 수 있습니다. 다음은이 방법을 사용하는 memcpy의 예입니다.

void duff_memcpy( char* to, char* from, size_t count ) {
    size_t n = (count+7)/8;
    switch( count%8 ) {
    case 0: do{ *to++ = *from++;
    case 7:     *to++ = *from++;
    case 6:     *to++ = *from++;
    case 5:     *to++ = *from++;
    case 4:     *to++ = *from++;
    case 3:     *to++ = *from++;
    case 2:     *to++ = *from++;
    case 1:     *to++ = *from++;
            }while(--n>0);
    }
}

이름으로 Algol 전달 (C 구문을 사용하여 설명) :

int a[3] = { 1, 2, 3 };
int i = 1;

void f(int j)
{
    int k;
    k = j;  // k = 2
    i = 0;
    k = j;  // k = 1 (!?!)    
}

int main()
{
    f(a[i]);
}

자바 :

int[] numbers() {
  return null;
}

다음과 같이 작성할 수 있습니다.

int numbers() [] {
  return null;
}

Python에서 :

>>> x=5
>>> 1<x<10
True
>>> 1<x<3
False

WTF는 아니지만 유용한 기능입니다.


INTERCAL 은 아마도 가장 이상한 언어 기능에 대한 최고의 개요 일 것입니다. 개인적으로 가장 좋아하는 것은 GOTO와 거의 반대되는 COMEFROM 문입니다.

COMEFROM is roughly the opposite of GOTO in that it can take the execution state from any arbitrary point in code to a COMEFROM statement. The point in code where the state transfer happens is usually given as a parameter to COMEFROM. Whether the transfer happens before or after the instruction at the specified transfer point depends on the language used. Depending on the language used, multiple COMEFROMs referencing the same departure point may be invalid, be non-deterministic, be executed in some sort of defined priority, or even induce parallel or otherwise concurrent execution as seen in Threaded Intercal. A simple example of a "COMEFROM x" statement is a label x (which does not need to be physically located anywhere near its corresponding COMEFROM) that acts as a "trap door". When code execution reaches the label, control gets passed to the statement following the COMEFROM. The effect of this is primarily to make debugging (and understanding the control flow of the program) extremely difficult, since there is no indication near the label that control will mysteriously jump to another point of the program.


Not really a language feature, but an implementation flaw: Some early Fortran compilers implemented constants by using a constant pool. All parameters were passed by reference. If you called a function, e.g.

f(1)

The compiler would pass the address of the constant 1 in the constant pool to the function. If you assigned a value to the parameter in the function, you would change the value (in this case the value of 1) globally in the program. Caused some head scratching.


Don't know if it can be considered a language feature, but, in C++ almost any compiler error related to templates delivers a fair amount of WTF to many C++ programmers around the world on daily basis :)


I would say the whole whitespace thing of Python is my greatest WTF feature. True, you more-or-less get used to it after a while and modern editors make it easy to deal with, but even after mostly full time python development for the past year I'm still convinced it was a Bad Idea. I've read all the reasoning behind it but honestly, it gets in the way of my productivity. Not by much, but it's still a burr under the saddle.

edit: judging by the comments, some people seem to think I don't like to indent my code. That is an incorrect assessment. I've always indented my code no matter what the language and whether I'm forced to or not. What I don't like is that it is the indentation that defines what block a line of code is in. I prefer explicit delimiters for that. Among other reasons, I find explicit delimiters makes it easier to cut and paste code.

For example, if I have a block indented 4 spaces and paste it at the end of a block that is indented 8 spaces, my editor (all editors?) have no idea if the pasted code belongs to the 8-space block or the outer block. OTOH, if I have explicit delimiters it's obvious which block the code belongs to and how it should be (re-)indented -- it does so by intelligently looking for block delimiters.

edit 2: some people who provide comments seem to think this is a feature I hate or that I think makes python a poor language. Again, not true. While I don't like it all that much, that's beside the point. The question is about the strangest language feature, and I think this is strange, by virtue of it being something very, very few (but >0) languages use.


The many name spaces of C:

typedef int i;

void foo()
{
    struct i {i i;} i;
    i: i.i = 3;
    printf( "%i\n", i.i);
}

Or with characters:

typedef char c;

void foo()
{
    struct c {c c;} c;
    c: c.c = 'c';
    printf( "%c\n", c.c);
}

I struggled a bit about this:

1;

In perl, modules need to return something true.


I'm surprised that no one has mentioned Visual Basic's 7 loop constructs.

For i As Integer = 1 to 10 ... Next
While True ... End While
Do While True ... Loop
Do Until True ... Loop
Do ... Loop While True
Do ... Loop Until True
While True ... Wend

Because sticking an ! in front of your conditional is way too complicated!


For those who don't know, bc is an "arbitrary precision calculator language", and I use it quite often for quick calculations, particularly when the numbers involved are large ($ is the prompt):

$ bc -lq
12^345
20774466823273785598434446955827049735727869127052322369317059031795\
19704325276892191015329301807037794598378537132233994613616420526484\
93077727371807711237016056649272805971389591721704273857856298577322\
13812114239610682963085721433938547031679267799296826048444696211521\
30457090778409728703018428147734622401526422774317612081074841839507\
864189781700150115308454681772032

bc has been a standard Unix command for a long time.

Now for the "WTF feature". This is from man bc (emphasis mine):

quit: When the quit statement is read, the bc processor is terminated, regardless of where the quit statement is found. For example, "if (0 == 1) quit" will cause bc to terminate.

halt: The halt statement (an extension) is an executed statement that causes the bc processor to quit only when it is executed. For example, "if (0 == 1) halt" will not cause bc to terminate because the halt is not executed.


I always wondered why the simplest program was:

class HelloWorldApp {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

Whereas it could be:

print "Hello World!"

Maybe this is to frighten computer science students in the first place ...


JavaScript is object oriented, right? So running methods on literal strings and numbers should work. Like "hello".toUpperCase() and 3.toString(). Turns out that second one is a syntax error, why? Because the parser expects a number followed by a dot to be a floating point literal. That's not the WTF, the WTF is that you only have to add another dot to make it work:

3..toString()

The reason is that the literal 3. is interpreted as 3.0, and 3.0.toString() works fine.


In JavaScript:

2 == [2]

// Even stranger
2 == [[[2]]]

// And down-right nutty
var a = { "abc" : 1 };
a[[[["abc"]]]] === a["abc"]; // this is also true

Luckily the kind folks at stackoverflow.com explained the whole thing to me: Why does 2 == [2] in JavaScript?


My biggest most hated feature is any configuration file syntax which includes conditional logic. This sort of thing is rife in the Java world (Ant, Maven, etc. You know who you are!).

You just end up programming in a c**p language, with limited debugging and limited editor support.

If you need logic in your configuration the "Pythonic" approach of coding the configuration in a real language is much much better.


powerbasic (www.powerbasic.com) includes the compiler directive:

# BLOAT {bloatsize}

this increases the size of the compiled executable by <bloatsize> bytes. this was put in the compiler in case people creating the executable don't like the small size of the generated executable. it makes the EXE seem bigger to compete with bloated programming languages:)

참고URL : https://stackoverflow.com/questions/1995113/strangest-language-feature

반응형