Sizce karşılaştığınız en şaşırtıcı, garip, garip veya gerçekten "WTF" dil özelliği nedir?
Lütfen cevap başına yalnızca bir özellik.
Sizce karşılaştığınız en şaşırtıcı, garip, garip veya gerçekten "WTF" dil özelliği nedir?
Lütfen cevap başına yalnızca bir özellik.
Yanıtlar:
C'de diziler şu şekilde dizine eklenebilir:
a[10]
ki bu çok yaygın.
Bununla birlikte, daha az bilinen form (gerçekten işe yarar!):
10[a]
bu yukarıdakiyle aynı anlama gelir.
JavaScript'te:
'5' + 3 gives '53'
Buna karşılık
'5' - 3 gives 2
+
dize birleştirme için korkunç
JavaScript'te aşağıdaki yapı
return
{
id : 1234,
title : 'Tony the Pony'
};
return , sonraki satırsonuna gizli gizli noktalı virgül eklenmesi nedeniyle bir sözdizimi hatasıdır undefined
return
. Ancak, beklediğiniz gibi çalışır:
return {
id : 1234,
title : 'Tony the Pony'
};
Daha da kötüsü, bu da işe yarıyor (en azından Chrome'da):
return /*
*/{
id : 1234,
title : 'Tony the Pony'
};
İşte aynı sorunun bir sözdizimi hatası vermeyen bir çeşidi, sessizce başarısız oluyor:
return
2 + 2;
JavaScript doğruluk tablosu:
'' == '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
Kaynak: Doug Crockford
==
dil tasarımcısının gözünde hangi amaca hizmet ediyor?
==
anlamı olsaydı iyi olurdu ===
, ve sonra başka bir operatör vardı, böyle bir ~=
zorlamaya izin veren bir şey vardı .
C ve C ++ 'daki trigraflar.
int main() {
printf("LOL??!");
}
LOL|
Üçgen ??!
dönüştürüldüğünden , bu yazdırılacaktır |
.
Otomatik boks ve Java'da tam sayı önbellek ile eğlenceli:
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 kaynak koduna hızlı bir bakış aşağıdakileri sağlayacaktır:
/**
* 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);
}
Not: bir özellik tarafından ayarlanmadığı sürece IntegerCache.high
varsayılan 127
olarak kullanılır.
Otomatik boks ile olan şey, açıkça oluşturulmadıkça hem foo'nun hem de çubuğun önbellekten alınan aynı tamsayı nesnesinin olmasıdır: örneğin foo = new Integer(42)
, referans eşitliğini karşılaştırırken, yanlış yerine doğru olacaktır. Tamsayı değerini karşılaştırmanın doğru yolu.equals;
Neil Fraser'den alıntı (o sayfanın sonuna bakın),
try {
return true;
} finally {
return false;
}
(Java'da, ancak görünüşe göre JavaScript ve Python'da aynıdır). Sonuç okuyucuya bir alıştırma olarak bırakılır.
DÜZENLENEN: Konuyla ilgili olduğumuz sürece şunu da dikkate alın:
try {
throw new AssertionError();
} finally {
return false;
}
Control cannot leave the body of a finally clause
return
de finally
fıkra.
APL (TÜMÜ dışında), herhangi bir programı tek bir satırda yazma yeteneği.
örneğin APL'de bir satırda Conway'in Hayat Oyunu :
alternatif metin http://catpad.net/michael/APLLife.gif
Bu çizgi WTF değilse, hiçbir şey!
Ve işte bir video
C ++ şablonlarının kullanılabileceği garip şeyler, en iyi şekilde "çizilmiş" şekiller alanını hesaplamak için şablonlar kullanan "Çok Boyutlu Analog Değişmezler" tarafından gösterilebilir . Aşağıdaki kod 3x3 dikdörtgen için geçerli C ++
#include"analogliterals.hpp"
using namespace analog_literals::symbols;
unsigned int c = ( o-----o
| !
! !
! !
o-----o ).area;
Veya, 3D küp içeren başka bir örnek:
assert( ( o-------------o
|L \
| L \
| L \
| o-------------o
| ! !
! ! !
o | !
L | !
L | !
L| !
o-------------o ).volume == ( o-------------o
| !
! !
! !
o-------------o ).area * int(I-------------I) );
Perl'in birçok yerleşik değişkeni:
$#
- yorum değil !$0
, $$
ve $?
- tıpkı aynı ada sahip kabuk değişkenleri gibi$ˋ
,, $&
ve $'
- garip eşleşen değişkenler$"
ve $,
- liste ve çıktı alanı ayırıcıları için garip değişkenler$!
- errno
sayı gibi , ancak strerror(errno)
dize gibi$_
- gizli değişken, her zaman kullanılır ve hiç görülmemiş$#_
- son altyordam argümanının dizin numarası ... belki@_
- geçerli işlevin (non) adları ... belki$@
- son istisna%::
- sembol tablosu$:
, $^
, $~
, $-
, Ve $=
- şey çıktı formatları ile ilgisi$.
ve $%
- giriş satırı numarası, çıkış sayfası numarası$/
ve $\
- giriş ve çıkış kayıt ayırıcılar$|
- çıkış tamponlama kontrolörü$[
- dizi tabanınızı 0 tabanlı yerine 1 tabanlı olarak 42 tabanlı olarak değiştirin: WHEEE!$}
- hiçbir şey, garip bir şekilde!$<
, $>
, $(
, $)
- gerçek ve etkili UIDs ve Gıd'ler@ISA
- mevcut paketin doğrudan üst sınıflarının isimleri$^T
- dönem saniye olarak komut dosyası başlangıç zamanı$^O
- mevcut işletim sistemi adı$^V
- Perl'in hangi sürümüBunların nereden geldiği çok daha fazlası var. Listenin tamamını buradan okuyun .
$[
Değişken hepsini en kötülüktür.
perldoc perlvar
her beş saniyede bir kontrol etmek zorunda kalmadan kodlayabileceğiniz bir şey olsaydı kesinlikle takdir ediyorum . (Kontrol ettiğim zamanın yarısını "Bunu benim için yapabilen özel bir değişken olduğunu biliyorum, hangisini hatırlamıyorum ..." = P)
use English;
RegExp performansını etkilemesidir. Bunu telafi etmiyorum. perldoc.perl.org/English.html#PERFORMANCE
/$foo[bar]/
, [bar]
bölüm bir karakter sınıfı mı yoksa diziye abone @foo
mi? Korkunç cevap için perldata Grep.
PHP'nin dizelerdeki sayısal değerleri işlemesi . Tüm ayrıntılar için farklı bir soruya verilen bu önceki cevaba bakın , ancak kısaca:
"01a4" != "001a4"
Farklı sayıda karakter içeren iki dizeniz varsa, bunlar eşit sayılamaz. Baştaki sıfırlar önemlidir, çünkü bunlar sayı değil dizelerdir.
"01e4" == "001e4"
PHP dizeleri sevmez. Değerlerinizi sayı olarak ele almak için bulabileceği herhangi bir mazeret arıyor. Bu dizelerdeki onaltılı karakterleri biraz değiştirin ve aniden PHP bunların artık dizge olmadığına karar verir, bilimsel gösterimdeki sayılardır (PHP tırnak kullandığınız umurumda değildir) ve eşdeğerdir çünkü önde gelen sıfırlar sayılar için yok sayılır. Bu noktayı güçlendirmek için PHP'nin de "01e4" == "10000"
doğru olarak değerlendirildiğini göreceksiniz çünkü bunlar eşdeğer değerlere sahip sayılardır. Bu belgelenmiş davranış, pek mantıklı değil.
Ayrılmış kelimeleri ortadan kaldırmaya çalışan tüm diller (PL / I gibi) için bir oy verelim.
Başka nerede yasal olarak eğlenceli ifadeler yazabilirsiniz:
IF IF THEN THEN = ELSE ELSE ELSE = THEN
( IF
, THEN
, ELSE
Değişken isimler)
veya
IF IF THEN THEN ELSE ELSE
( IF
bir değişkendir THEN
ve ELSE
altyordamlardır)
JavaScript sekizlik dönüşüm 'özelliği' bilmek iyi bir şeydir:
parseInt('06') // 6
parseInt('07') // 7
parseInt('08') // 0
parseInt('09') // 0
parseInt('10') // 10
Daha fazla ayrıntı burada .
C'de bir do / while anahtar deyimi ile geçebilir. İşte bu yöntemi kullanan bir memcpy örneği:
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);
}
}
while
sonunda, JMP
geri do
atlayıp neden do
döngüde kaldığınızı açıklayan bir (koşullu) 'a geri döner .
Algol isme göre geçiş (C sözdizimi kullanılarak gösterilmiştir):
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]);
}
def f(j : => int)
)
... template<typename T> struct by_name { virtual operator T&() = 0; }; void f(by_name<int> j) { ... } int main() { f(struct : by_name<int> { operator int&() { return a[i]; } }); }
mi?
Python'da:
>>> x=5
>>> 1<x<10
True
>>> 1<x<3
False
WTF değil, kullanışlı bir özellik.
(10 > 5 > 1) != ((10 > 5) > 1)
Python'da.
(funct_a(5)+5 > b > funct_a(5))
sadece bir funct_a(5)
kez arar . BÜYÜK bir özellik!
funct_a
bu örnekte iki kez çağrılacak. İçinde b > funct_a(5) > c
aksine, sadece bir kez çağrılacaktır b > funct_a(5) and funct_a(5) > c
.
Java dilinde:
int[] numbers() {
return null;
}
Şu şekilde yazılabilir:
int numbers() [] {
return null;
}
const T*
ve T const*
eşdeğerdir, bu T* const
işaretçiyi sabitler. Ayrıca, sans yazı tiplerinden nefret ediyorum.
numbers()[2]
yasal bir açıklama.
INTERCAL muhtemelen en garip dil özelliklerinin en iyi özeti. Benim kişisel favorim GOTO'nın (neredeyse) tam tersi olan COMEFROM ifadesidir.
COMEFROM, yürütme durumunu koddaki herhangi bir keyfi noktadan bir COMEFROM deyimine götürebilmesi nedeniyle GOTO'nın kabaca tersidir. Durum aktarımının gerçekleştiği koddaki nokta genellikle COMEFROM'a bir parametre olarak verilir. Aktarımın, belirtilen aktarım noktasındaki talimattan önce veya sonra gerçekleşip gerçekleşmediği kullanılan dile bağlıdır. Kullanılan dile bağlı olarak, aynı kalkış noktasına gönderme yapan birden fazla COMEFROM, geçersiz olabilir, belirleyici olmayabilir, belirli bir tür öncelikte yürütülebilir, hatta Dişli Aralıklı'da görüldüğü gibi paralel veya başka bir şekilde eşzamanlı yürütme indükleyebilir. "COMEFROM x" ifadesinin basit bir örneği, "tuzak kapısı" görevi gören x etiketidir (karşılık gelen COMEFROM'un yakınında fiziksel olarak herhangi bir yere yerleştirilmesi gerekmez). Kod yürütme etikete ulaştığında, kontrol COMEFROM'dan sonra ifadeye aktarılır. Bunun etkisi, hata ayıklamayı (ve programın kontrol akışını anlamak) son derece zorlaştırmaktır, çünkü etiketin yanında, kontrolün gizemli bir şekilde programın başka bir noktasına atlayacağına dair bir gösterge yoktur.
PLEASE
değiştiriciyi yeterince kullanmıyorsanız programı derlemeyi reddedebilir !
Gerçekten bir dil özelliği değil, bir uygulama hatası: Bazı erken Fortran derleyicileri sabit bir havuz kullanarak sabitleri uyguladı. Tüm parametreler referans ile geçti. Bir işlevi çağırdıysanız, ör.
f(1)
Derleyici, sabit havuzdaki sabit 1'in adresini işleve geçirir. İşlevdeki parametreye bir değer atarsanız, programdaki değeri (bu durumda 1 değerini) global olarak değiştirirsiniz. Bazı kafa çizilmelerine neden oldu.
2+2
olabilir5
( 2
elbette çok büyük değerler için !).
2+2
eşit olur ). 5
5
2 + 2 = 5
; sözdizimi hatası olur. Gerçek olacak olan 2 + 2 .EQ. 5
.
Bir dil özelliği olarak kabul edilip edilemeyeceğini bilmiyorum, ancak C ++ 'da şablonlarla ilgili hemen hemen her derleyici hatası, dünyadaki birçok C ++ programcısına günlük olarak adil miktarda WTF sağlar :)
std::vector<std::pair<int, std::complex>, std::allocator<std::pair<int, std::complex> > >::vector< std::vector<std::pair<int, std::complex>, std::allocator<std::pair<int, std::complex> > >::iterator>(std::vector<std::pair<int, std::complex>, std::allocator<std::pair<int, std::complex> > >::iterator, std::vector<std::pair<int, std::complex>, std::allocator<std::pair<int, std::complex> > >::iterator, std::allocator<std::pair<int, std::complex> >)
C'nin birçok isim alanı:
typedef int i;
void foo()
{
struct i {i i;} i;
i: i.i = 3;
printf( "%i\n", i.i);
}
Veya karakterlerle:
typedef char c;
void foo()
{
struct c {c c;} c;
c: c.c = 'c';
printf( "%c\n", c.c);
}
Python'un tüm beyaz alanı benim en büyük WTF özelliğim olduğunu söyleyebilirim. Doğru, bir süre sonra az ya da çok alışmaya başladınız ve modern editörler başa çıkmayı kolaylaştırıyor, ancak geçen yıl için çoğunlukla tam zamanlı python geliştirmesinden sonra bile bunun kötü bir fikir olduğuna ikna oldum. Arkasındaki tüm gerekçeleri okudum ama dürüst olmak gerekirse, üretkenliğimin önüne geçiyor. Çok değil, ama hala eyer altında bir çapak.
edit: yorumlara bakılırsa, bazı insanlar kodumu girintilemek istemediğimi düşünüyor. Bu yanlış bir değerlendirmedir. Dil ne olursa olsun ve zorlanıp zorlanmadığımdan bağımsız olarak kodumu her zaman girintili yaptım. Ne sevmiyorum hangi bir kod satırı içinde blok tanımlayan girinti olmasıdır. Bunun için açık sınırlayıcıları tercih ederim. Diğer nedenlerin yanı sıra, kodları kesip yapıştırmayı kolaylaştıran açık sınırlayıcılar buluyorum.
Örneğin, 4 boşluk girintili bir bloğum varsa ve 8 boşluk girintili bir bloğun sonuna yapıştırırsam, yapıştırılan kodun 8 boşluk bloğuna veya dış kısma ait olup olmadığı konusunda editörüm (tüm editörler?) blok. OTOH, açık sınırlayıcılarım varsa, kodun hangi bloğa ait olduğu ve nasıl (yeniden) girintili olması gerektiği açıktır - bunu akıllıca blok sınırlayıcıları arayarak yapar.
edit 2: yorum yapan bazı insanlar bunun nefret ettiğim bir özellik olduğunu veya python'u kötü bir dil haline getirdiğini düşünüyor gibi görünüyor. Yine doğru değil. Ben o kadar çok sevmesem de, konunun yanında. Soru en tuhaf dil özelliği ile ilgili ve bence bu çok garip, çok az (ama> 0) dilin kullandığı bir şey olması.
Bu konuda biraz mücadele ettim:
1;
Perl'de, modüllerin gerçek bir şey döndürmesi gerekir .
'Cogito ergo sum';
Herkesin bildiği gibi olası tüm evrenlerde açıkça doğru olduğu çok nadiren kullandım . Bu, maksimum taşınabilirlik sağlar."
<?=1;?>
1. <?=true;?>
döndürür 1. <?=false;?>
döndürür null.
Hiç kimsenin Visual Basic'in 7 döngü yapısından bahsetmediğine şaşırdım .
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
Çünkü bir yapışma! Şartlı önünde olan yolu çok karmaşık!
While
ve Whend
" yapmalıydılar , çünkü sessizce labialised velar yaklaşımı ile "while" kelimesini telaffuz eden bazı insanlar var. Ve tabii ki daha güzel sıralar ve sıralayan kod güzel.
Bilmeyenler için, bc
"keyfi bir hassas hesap makinesi dili" dir ve özellikle ilgili sayılar büyük olduğunda ( $
istemdir) hızlı hesaplamalar için oldukça sık kullanırım :
$ bc -lq
12^345
20774466823273785598434446955827049735727869127052322369317059031795\
19704325276892191015329301807037794598378537132233994613616420526484\
93077727371807711237016056649272805971389591721704273857856298577322\
13812114239610682963085721433938547031679267799296826048444696211521\
30457090778409728703018428147734622401526422774317612081074841839507\
864189781700150115308454681772032
bc
uzun zamandır standart bir Unix komutu olmuştur.
Şimdi "WTF özelliği" için. Bu man bc
(benim vurgu):
quit : quit deyimi okunduğunda, quc deyiminin bulunduğu yerden bağımsız olarak bc işlemcisi sonlandırılır. Örneğin, "if (0 == 1) quit" bc'nin sonlanmasına neden olur.
halt : halt deyimi (bir uzantı), bc işlemcisinin yalnızca yürütüldüğünde çıkmasına neden olan yürütülen bir deyimdir. Örneğin, "if (0 == 1) dur" durma işlemi yürütülmediği için bc'nin sonlandırılmasına neden olmaz.
bc
ve bc
yazı sayfamdaki büyük alıntılardan dolayı yazımda yazmak istedim .
echo '[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq'|dc
(bunu zaten biliyor olsanız da).
Her zaman en basit programın neden olduğunu merak ettim:
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
Halbuki olabilir:
print "Hello World!"
Belki de bu bilgisayar bilimi öğrencilerini ilk etapta korkutmaktır ...
JavaScript nesne yönelimli, değil mi? Yani değişmez dizgiler ve sayılar üzerinde çalışan yöntemler çalışmalıdır. Gibi "hello".toUpperCase()
ve 3.toString()
. İkincisinin bir sözdizimi hatası olduğu ortaya çıkıyor, neden? Ayrıştırıcı bir sayının ardından noktanın kayan nokta değişmezi olmasını beklediğinden. Bu WTF değil, WTF, çalışması için sadece başka bir nokta eklemeniz gerektiğidir:
3..toString()
Sebebi, edebi 3.
olarak yorumlanır 3.0
ve 3.0.toString()
iyi çalışır.
3..__add__(4)
). Sonra tekrar ben bunu (3).__add__(4)
yapmak için çok daha az beyin hasarlı yolu olduğunu düşünüyorum :)
3.0.toString()
gözlerimi kaşındırıyor.
JavaScript'te:
2 == [2]
// Even stranger
2 == [[[2]]]
// And down-right nutty
var a = { "abc" : 1 };
a[[[["abc"]]]] === a["abc"]; // this is also true
Neyse ki stackoverflow.com'daki nazik insanlar bana her şeyi açıkladı: Neden JavaScript'te 2 == [2]?
===
yerine kullanmalısınız .
Number(n)
Benzer bir şey yapmak için de kullanabilirsiniz . Ne yazık ki her iki çözümümüzde de ===
mola = (.
En çok nefret ettiğim özellik, koşullu mantık içeren herhangi bir yapılandırma dosyası sözdizimidir. Bu tür şeyler Java dünyasında yaygındır (Ant, Maven, vb. Kim olduğunu biliyorsun!).
Sınırlı hata ayıklama ve sınırlı editör desteği ile ac ** p dilinde programlamaya son verdiniz.
Yapılandırmanızda mantığa ihtiyacınız varsa, yapılandırmayı gerçek bir dilde kodlamak için "Pitonik" yaklaşım çok daha iyidir.
powerbasic (www.powerbasic.com) derleyici yönergesini içerir:
# BLOAT {bloatsize}
bu, derlenen yürütülebilir dosyanın <bloatsize>
bayt boyutunu artırır . çalıştırılabilir öğeyi oluşturan kişilerin oluşturulan çalıştırılabilir öğenin küçük boyutlarından hoşlanmaması durumunda derleyiciye konulmuştur. EXE'nin şişirilmiş programlama dilleriyle rekabet etmek için daha büyük görünmesini sağlar :)