2010-11-29 16 views
9

Kompilator Scala kompiluje bezpośrednio do kodu bajtowego Java (lub .NET CIL). Niektóre funkcje Scala mogą być ponownie wykonane w Javie bezpośrednio (na przykład proste w zrozumieniu, zajęciach, tłumaczeniu funkcji anonimowych/wewnętrznych itd.). Jakie funkcje nie mogą być przetłumaczone w ten sposób?Jakie funkcje Scala nie mogą być tłumaczone na język Java?

To jest prawdopodobnie głównie z zainteresowań naukowych. Bardziej pożytecznie, być może, jakie są kluczowe cechy lub idiomy Scali, których używasz, których nie można łatwo przedstawić w Javie?

Czy są jakieś inne sposoby? Rzeczy, które można zrobić bezpośrednio w Javie, które nie mają bezpośredniego odpowiednika w Scali? Idiomy w Javie, które nie tłumaczą?

+0

Dobre pytanie z dobrymi odpowiedziami. Wygląda na to, że porównując Scalę z Javą, ludzie w końcu dostają, że wszystkie języki są równie potężne, ale oferują różne abstrakcje, które mają różne (dis) zalety. – Raphael

Odpowiedz

10

To pytanie, moim zdaniem, pomija punkt, pytając nas o porównanie języków JVM, patrząc na ich wygenerowany kod bajtowy.

Scala kompiluje do kodu bajtowego równoważnika Java. Oznacza to, że kod bajtowy mógł zostać wygenerowany przez kod napisany w Javie. Rzeczywiście można nawet uzyskać scalac, aby wyprowadzić formularz pośredni, który wygląda podobnie jak Java.

Wszystkie funkcje, takie jak cech (przez spedytorów statycznych), nielokalnych zwrotów (przez wyjątkami), wartości leniwe (przez referencje) etc są eksprymowanej przez program Java, choć być może w sposób najbardziej brzydkie!

Ale co sprawia, że ​​Scala Scala i nie Java co scalac może zrobić dla ciebie, zanim kod bajtowy jest generowany. To, do czego zmierza język statycznie napisany, to zdolność sprawdzania poprawności programu, w tym poprawności typu (zgodnie z jego typem , system typu) podczas kompilacji.

Główną różnicą następnie między Java i Scala (jak oczywiście Java jest również statycznie wpisane), jest więc systemem typ Scala, która jest zdolna do wyrażania stosunków, które układ typu java-na-language za nie mogę programowe .Na przykład:

class Foo[M[_], A](m : M[A]) 
trait Bar[+A] 

koncepcji, że M jest parametrem typu, która sama ma typ parametrów lub że Bar jest kowariantna, po prostu nie istnieje w Java-land.

+0

Myślałem, że nie jest konieczne, aby wszystkie możliwości kodu bajtowego Java mogły być generowane z programu źródłowego Java? Tak więc mogą istnieć przypadki, w których Scalac może generować ten javac cannnot i vice versa. –

+0

To prawda, ale scala specjalnie * nie * wziął tę trasę. Prawie wszystkie bajty emitowane przez scala mogły być emitowane z programu Java. Ale podstawową kwestią jest to, że to nie * bajty * definiują scala i co scala może zrobić dla ciebie. –

+0

Zgoda. Ciekaw jestem jednak różnicami (Tło: znam (bardzo) małą Javę i uczę się Scali.) Podoba mi się to, co wiem o Scali, ale zastanawiam się, ile frustracji stawiam sobie gdy powracam do Java, to tak, jak wtedy, gdy nauczyłem się Lisp - to zmieniło sposób, w jaki napisałem we wszystkich językach, ale niektóre rzeczy w Lisp są prawie niemożliwe w językach takich jak C. –

11

Cechy to jedna rzecz, która nie ma odpowiednika. Cechy to interfejsy z kodem w nich. Możesz skopiować kod do wszystkich klas, które mają mieszaną cechę, ale to nie to samo.

Sądzę, że system typu scala jest bardziej kompletny. Podczas gdy w końcu zostanie odwzorowany na typy JVM (w rzeczywistości cierpią one na wymazanie). Możesz wyrazić pewne rzeczy w systemie typu Scala, które mogą nie być możliwe w Javie (np. Wariancje).

4

Myślę, że nie ma odpowiednika dynamicznego miksu w niektórych Cechach. W Scali możesz dodać w momencie tworzenia nowych obiektów niektóre cechy, które są zmieszane.

Na przykład tworzymy jednego psa, który jest głodny i spragniony, i jednego psa, który jest po prostu głodny.

val hungryThirstyDog = new Dog with Hungry with Thirsty 
val onlyHungryDog = new Dog with Hungry 

Nie wiem, równoważny sposób to zrobić w Javie. W języku Java dziedziczenie jest zdefiniowane statycznie.

+0

Czy istnieje sposób rozwiązania tego samego problemu projektowego w Javie przy użyciu innej techniki? –

+0

@Paul Definiuj "rozwiązuj", "łatwo reprezentuj", "wyrażaj naturalnie" itp. W przypadku składanki mixin podobne problemy są rozwiązywane w Javie przy użyciu składu obiektu (ma-a) i iniekcji zależności, ale techniki te wprowadzają niepotrzebne zależności i/lub wymagają więcej blachy. –

+0

Nie zamierzam określać wszystkich warunków. Zakładam, że czytelnik może zinterpretować. Dzięki za odpowiedzi. –

4

Implicyjne konwersje nie mają bezpośredniego odpowiednika w Javie.

+0

Ale prawdopodobnie można to zrobić jednoznacznie? Jest to wygoda (przydatna na pewno), a nie różnica w wyrazistości. Interesuje mnie zbadanie, do jakiego stopnia Scala pozwala ci wyrażać rzeczy bardziej "naturalnie" (dla pewnych wartości "naturalnych"). –

+1

Kiedy wyrażamy siebie w języku naturalnym, często wymuszamy aspekty kontekstu, które są przyjmowane jako oczywiste przez Podobnie, jeśli chodzi o programowanie w Scali, to całkiem naturalne wydaje mi się usuwanie parametrów lub konwersji, które wynikają z kontekstu lub z domyślnych założeń –

+0

Tak, dobry komentarz. . –

4

Jedną z cech scali, z której korzystałem, jest reifikacja typu za pomocą Manifesty. Ponieważ JVM usuwa wszystkie informacje o typach generycznych, scala pozwala zachować te informacje w zmiennych. Jest to coś, z czym Java AFAIK nie może sobie poradzić, ponieważ nie ma argumentów dla typów w kodzie bajtowym.

Sprawa, której potrzebowałem, polegała na dopasowaniu wzoru do typu List. To jest, miałem obiekt VertexBuffer, który przechowuje dane na GPU, które mogą być zbudowane z listy zmiennych lub liczb całkowitych. Kod Oczywisty wyglądał w przybliżeniu tak:

class VertexBuffer[T](data:List[T])(implicit m:Manifest[T]) { 
    m.toString.match { 
    case "float" => ... 
    case "int" => ... 
    } 
} 

This link linki do blogu z dodatkowymi informacjami.

Istnieje wiele stron SO zawierających więcej informacji, takich jak this one.

+0

Oczywiście można wymagać od dzwoniącego jawnego przekazania 'klasy ' w Javie. –

+0

Albo jakikolwiek identyfikator, taki jak wyliczenie. Scala's jest czystsza, ale myślę, że to nie jest wielka różnica. – nullspace

0

Twój temat nie jest jasny, ale masz na myśli Java JVM lub Java w tym języku. Biorąc pod uwagę, że Scala działa na JVM, q nie ma sensu, ponieważ wszyscy wiemy, że Scala działa na JVM.

+0

Myślę, że jest już jasne, ale dla jasności mam na myśli Javę w języku –

+0

Z definicji jest to możliwe, aby wyrazić dowolną konstrukcję scala w języku Java, nawet jeśli jest tam dużo tablic bojlerowych i głośno. –

+1

Nie, jest to prawdą tylko wtedy, gdy istnieje program Java, który może wytworzyć wszystkie prawidłowe sekwencje kodu bajtowego. Nie mam pojęcia, czy to prawda, ale to nie jest dane. I użyłem słowa "straighforward" w pytaniu. Java i Scala są równoważne pod tym względem, że oba są kompletne, ale wyrazistość, klarowność itd. Mogą się różnić. Właśnie to było po –

Powiązane problemy