dsl編譯語言
⑴ F#是比 Scala 更好的語言嗎
經有人問java的創始人高斯林這樣一個問題,「除了Java語言以外,您現在還使用JVM平台上的哪種編程語言?」他毫不猶豫的說是Scala。Scala到底是什麼?在目前眾多的JVM語言當中,Scala無疑是最引人注意的語言之一。Scala是一個靜態語言,更適合大型工程項目,Scala直接編譯成Java位元組碼,性能接近Java。Scala是一個多範式的語言,你可以混合使用函數式和面向對象編程,混合使用可變類和不變類,混合使用Actor和傳統的Java並發庫。短短一個月的時間,Scala於本月沖進了TIOBE的前五十名。一個Twitter的開發人員說過,Scala將會成為現代Web2.0的發起語言。LinkedIn也用這種語言。同樣許多其他大的公司如SonyPicture,EDF,SAP也開始使用這種語言。為什麼Scala發展這么迅猛,可以獲得如此熱烈的社區支持。曾冠東還表示,Scala不是Java的殺手,它無法取代Java的地位,也突破不了JVM的限制、Java實現不了的功能它也實現不了。我們可以將Scala形象的理解成大量語法糖的Java。Scala開發團隊發布了最新的2.9.2穩定版本,Scala語言的特性有許多,例如高階函數和對象、抽象類型綁定,actor使得函數在Scala中能是一個子類成為可能,Scala中的設計模式使得面向對象和函數編程無縫結合。Akka是一個用Scala編寫的庫,用於簡化編寫容錯的、高可伸縮性的Java和Scala的Actor模型應用。它已經成功運用在電信行業。Spark是一種可擴展的數據分析平台,它整合了內存計算的基元,因此,相對於Hadoop的集群存儲方法,它在性能方面更具優勢。Spark是在Scala語言中實現的,並且利用了該語言,為數據處理提供了獨一無二的環境。Scala編譯器可以生成位元組碼,直接運行在使用JVM上。該語言(它實際上代表了可擴展語言)被定義為可直接集成到語言中的簡單擴展。Scala作為一門靜態語言,它的主要特性有哪些?·Scala是面向對象的Scala是一個純面向對象語言,在某種意義上來講所有數值都是對象。對象的類型和行為是由class和trait來描述的。Class的抽象可由子類化和一種靈活的基於mixin的組合機制(它可作為多重繼承的簡單替代方案)來擴展。·Scala是函數式的Scala還是一個函數式語言,在某種意義上來講所有函數都是數值。Scala為定義匿名函數提供了一種輕量級的語法,它支持高階(higher-order)函數、允許函數嵌套、支持局部套用(currying)。Scala的case類及其內置支持的模式匹配模型代數類型在許多函數式編程語言中都被使用。·Scala是靜態類型的Scala配備了一套富有表現力的類型系統,該抽象概念以一種安全的和一致的方式被使用。·Scala是可擴展的Scala的設計承認了實踐事實,領域特定應用開發通常需要領域特定語言擴展。Scala提供了一個獨特的語言組合機制,這可以更加容易地以類庫的形式增加新的語言結構:任何方式可以被用作中綴(infix)或後綴(postfix)操作符閉包按照所期望的類型(目標類型)自動地被構造兩者結合使用可方便地定義新語句,無需擴展語法,也無需使用類似宏的元編程工具。·Scala可與Java和.NET進行互操作Scala設計時就考慮了與流行編程環境良好交互,如Java2運行時環境(JRE)和.NET框架(CLR)。特別是與主流面向對象語言,如Java和C#盡量無縫交互。Scala有像Java和C#一樣的編譯模型(獨立編譯,動態裝載類),允許訪問成千上萬的高質量類庫。在並發性方面,與Scala在.NET領域中的姐妹語言F#相似,Scala是針對「並發性問題」的解決方案之一,讓開發人員能夠更加輕松地專注於問題的實質,而不用考慮並發編程的低級細節。Actor編程模式讓高度並行應用程序的開發更加簡單。Scala把Erlang風格的基於actor的並發帶進了JVM。我們可以利用Scala的actor模型在JVM上設計具伸縮性的並發應用程序,以自動獲得多核心處理器帶來的優勢,而不必依照復雜的Java線程模型來編寫程序。Scala為並發性提供了兩種級別的支持,這與其他與Java相關的主題極為類似:首先,對底層庫的完全訪問(比如說java.util.concurrent)以及對「傳統」Java並發性語義的支持(比如說監控程序和wait()/notifyAll())。其次,這些基本機制上面有一個抽象層Scala提供了在穩定的高性能平台(Java虛擬機)上生成的能力同時也是一門敏捷性語言。這一類型的語言也有其他的選擇,例如Jython,JRuby,Groovy和Clojure,但是這些都是運行在JVM上的動態類型語言。OpenClass的效果讓大家會覺得Scala是動態語言,但它是選擇隱式轉換來實現的,這也正好證明了Scala是靜態語言。隱式轉換(Implicitconversion)使Scala具有類型安全性,正如擴展方法(extensionmethod)之於C#,開放類(openclass)之於ruby。即:向未曾定義的類型添加方法(如字元串、列表、整數)。這是使得Scala符合DSL(特定領域語言)模型的特性之一。Scala結合了面向對象和函數編程的優勢,函數編程的一個好處就是你能夠像運用一個數據那樣運用函數,可以用來定義真正高層級的庫,或者去定義新的領域特殊語言(DSL)。在談及Java與Scala的對比時,曾冠東表示,Scala能調用絕大部分的Java,而Java調用Scala獨有的東西會比較難。Java擁有非常強的概念規范,因此任何一個Java程序之間具有非常多的相似之處,並且這樣能夠方便的進行程序員交替。但是Scala並沒有這樣的統一性,因為這是一門很有表現力的語言。現場曾冠東為我們演示了實際案例,如下圖所示:正所謂,金無足赤,人無完人。Scala對二進制不兼容,語法也越來越復雜,不能突破Bytecode的限制、編譯速度有所緩慢。當它被廣泛用於單元測試、開發工具、Socket開發、以及面對多核挑戰的並發應用。總而言之,Scala是一種函數式面向對象語言,它融匯了許多前所未有的特性,而同時又運行於JVM之上。正如JRuby創建者之一CharlesNutter所宣稱的那樣Scala就是Java王位的合法繼承人。隨著開發者對Scala的興趣日增,以及越來越多的工具支持,無疑Scala語言將成為廣大軟體工程師手上一件必不可少的工具。
⑵ 編程語言的載體是什麼
編程語言通過編譯器裝換成計算機能理解的0101。通過cpu運算,把運算數據輸出到內存,通過編譯器裝換成文字,音頻,視頻,網頁等數據。
⑶ 日期+dsl是什麼意思啊
摘要 兩個意思,一個是數字用戶線路,另一個是領域特定語言。
⑷ DSlC這個理論是人類什麼語言
摘要 領域特定語言domain-specific language (DSL)是一種旨在特定領域下的上下文的語言。這里的領域是指某種商業上的(例如銀行業、保險業等)上下文,也可以指某種應用程序的(例如 Web 應用、資料庫等)上下文。與之相比的另一個概念是 通用語言general-purpose language (GPL,LCTT 譯註:注意不要和 GPL 許可證混淆),通用語言則可以廣泛應用於各種商業或應用問題當中。
⑸ 領域特定語言的定義
領域特定語言(domain-specific languages,簡稱DSL)
在定義DSL是什麼的問題上,Flowler認為目前經常使用的一些特徵,例如「關注於領域」、「有限的表現」和「語言本質」是非常模糊的。因此,唯一能夠確定DSL邊界的方法是考慮「一門語言的一種特定用法」和「該語言的設計者或使用者的意圖」:
如果XSLT的設計者將其設計為XML的轉換工具,那麼我認為XSLT是一個DSL。如果一個用戶使用DSL的目的是該DSL所要達到的目的,那麼它一個DSL,但是如果有人以通用的方式來使用一個DSL,那麼它(在這種用法下)就不再是一個DSL了。
以Fowler的觀點,DSL首先是一種幫助用戶從一個系統中抽象出某些部分的工具。所以「當你意識到你需要一個組件,或者當你已經有了一個組件而你希望簡化操作它的方式的時候」,DSL是有用的。使用DSL確實提供了某些益處。DSL不僅提高了代碼的易讀性,讓開發者可以和領域專家更好的交流,而且是改變執行上下文的一種手段,例如:把邏輯從編譯時切換到運行時,或者當命令式編程不是很合適的時候轉用聲明式計算模型。
⑹ swift是不是最新的一種編程語言
翻完iBooks書店上的The Swift Programming Language, 也下載了Xcode 6的beta版本來試驗了一下。現在可以評價一下。如發現不對的地方,請在評論中指出,我斟酌後進行修正。
主要從技術的角度。而商業的角度,吸引開發者,共同維護蘋果生態圈的繁榮等之類就不說了。
我不敢說swift學了有沒有用,可不可以掙更多錢,但這門語言還是比較有意思的。swift骨子裡面還是objc,但打扮過,比原來的模樣漂亮。個人感覺,蘋果還真的想用它取代objc呢。
------------------
swift 跟 objc 共用同一套的運行時環境
swift 的類型,可以橋接到 objc 的類型,反之亦然。如 string 對應原來objc的NSString, closures對應objc的block,等等。objc 積累下來的大量庫,實現不用改寫,swift 就直接可以使用。(最多加個聲明文件)。看兩個API的聲明,對比一下
objc
void
dispatch_apply(size_t iterations, dispatch_queue_t queue,
void (^block)(size_t));
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
swift
func dispatch_apply(iterations: UInt, queue: dispatch_queue_t!, block: ((UInt) -> Void)!)
func touchesBegan(touches: NSSet!, withEvent event: UIEvent!)
我懷疑,swift中的介面文件,是利用原來objc,c中的介面文件自動程序生成的。
同一個工程,可以同時使用swift, objc, c, c++ 四種編譯語言(額外嵌入的腳本語言另算)
原來的 iOS/Mac 工程,已經可以同時使用objc, c, C++三種語言。現在支持第四種。objc, c, c++三種語言的結合很容易, objc跟c本身就兼容,objc跟c++結合只要將文件名改成.mm。而swift跟其它語言的結合,需要另外的文件進行橋接,其實也挺方便的。
這里的橋接很容易,Apple自家的各種 C 庫移植過來了。比如Core Image/Audio,直接包含
import CoreAudio
import CoreImage
就可以使用了。
現在swift完全可以跟objc並存,原來的工程不建議重寫,也不用重寫。順其自然,慢慢讓它進化就是了。
swift 寫法看起來像腳本語言,但它是真正的編譯語言
初學者,看它使用了
let a = 4
var b = "hello"
沒有類型定義,就想當然的覺得它是腳本語言,解釋執行,這是錯誤的。上面兩行語句是用了類型推導,類似 C++ 裡面的auto。swift跟objc的運行時環境一樣,寫的程序跑起來不會比objc慢。swift區分了struct和class, 分別使用傳值跟傳引用。適當地使用struct,應該會比objc要快一點。
swift 吸收了很多其它語言的語法,寫起來比objc簡潔得多,不過它骨子裡面的概念,跟原來objc差不多
編程語言的語法重要,但是語法背後的概念更重要。比如面向對象,常用概念無非是,繼承,多態,封裝,信息隱藏等。繼承又可能分成多重繼承,介面繼承,實現繼承。或者還會有些嵌套類,嵌套函數等等。
當明白語法背後的概念,知道為什麼需要有這些東西。之後從一門語言切換到另一門有著相同概念的語言,其實很容易。
而語法會影響表達,理論上每門語言都可以表達任何概念。不過當某種概念在某門語言中,很難表達出來,就會傾向於不這樣使用它,這種概念在那門語言的社區就難以被人熟知。
感覺上,swift有著 obj-c, C++, Ruby的影子。
暫時,我自己最喜歡的3個特性有
tuple,終於可以返回多個數值了。一行交換兩個值。C++裡面的tie+tuple也可以實現類似功能,不過使用庫,顯得噪音太多。
closure,喜歡它的簡寫,還有在函數最後一參數,可以寫在()外面。這些特性,用來寫函數式風格的程序,會很好看。而原來objc的block, 還有c++的function, 就太啰嗦了。
switch,case裡面的條件匹配。
這些語法,編譯最後還是會映射成原來objc的運行模型。原來objc的概念,引用記數,ARC, 屬性,協議,介面,初始化,擴展類,匿名函數等等,繼續有效。
我將swift看成是objc的一塊大大的語法糖。
有個大塊頭的東西,是原來objc沒有的,就是泛型。swift中 將那種操作寫一次,就可以作用多個類型的語法叫做generics(泛型),而C++中稱為template(模板),叫法不同,本質是同樣的東西。
總的說來,swfit 涵蓋了現在流行的編程方式,結構化,面向對象,泛型,函數式。
swift的新語法,可以很好地支持內部DSL
有一種編程風格,不太好歸類。就是將程序拆分成,描述+解釋。解釋部分寫一次,其它地方使用描述式的語句,而不是命令式的語句。
內部DSL,通常利用主語言的語法特性,創出一套寫法,來寫一些描述性的語句。這些語句組合起來,就像一門新語言似得。這個比較難理解。舉個例子(從ruby那裡借過來的),假如計算,幾小時之後的秒數。C語言中,大概會寫成
getHourSeconds(3)
而現在 swift中,只要定義了擴展
extension Int
{
var hours:Int
{
return self * 3600
}
var ago:Int
{
return -self
}
}
就可以寫成
3.hours
3.hours.ago
分別是3小時後的秒數,3小時前的秒數。
同理,也可以寫成
10.days
10.days.ago
這種寫法,看起來跟原來的命令式寫法完全不同。這些程序是描述性的。原來的objc, 做不到這點。 我估計swift以後會冒出大量這樣風格的庫。
這種風格,到底好不好,要看情況。比較方便定義內部DSL的語言, 我自己知道的有C++, Ruby, Lisp。現在多了Swift。
認為所有人都是0基礎的,是錯誤的
有些人學得特別快,因為之前的基礎好。語言的語法只是表面,表面的東西總是變動得比較快的。底下的東西重要得多,而看不見。水面一塊冰,有些人是冰山露出一角,有些人是無根的浮冰。看起來差不多,其實差別十分之大。
我相信有些人,在兩個小時之內就可以使用這門新語言。
提提那個Playground
之前蘋果的員工,Bret Victor 演講過個視頻。提到這個這種可視化編程。當我們每一步操作,都得到實時地反饋,我們的做法會有很多不同,做出的東西也會不同。這個Playground,用來學習swift的特性很好用,不過我還不知道怎麼才能跟工程結合起來使用,不作評論。
⑺ groovy dsl if後面用什麼括弧
一種基於Java虛擬機的動態語言,可以和java無縫集成,正是這個特性,很多時候把二者同時使用,把groovy作為java的有效補充。對於Java程序員來說,學習成本幾乎為零。同時支持DSL和其他簡介的語法(例如閉包),使代碼便於閱讀。可以用groovy的動態特性來做規則引擎,在DB中維護腳本,業務變化的時候讓應用系統動態載入。
如果引入groovy在java工程中?
這個很簡單,不需要做別的事情,僅僅把groovy的二方包加入到pom文件中即可。例如:
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version> 1.8 . 3 </version>
</dependency>
java和groovy混合使用的方法有幾種?
1、 靜態編譯 ,在java工程中直接寫groovy的文件,然後可以在groovy的文件中引用java工程的類,這種方式能夠有效的利用groovy自身的語言特性,例如閉包;
2、通過 groovyShell 類直接執行腳本,例如:
package groovy_dsl.shell;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
public class GroovyShellEx {
public static void main(String[] args) {
Binding bind = new Binding();
bind.setVariable( "name" , "iamzhongyong" );
bind.setVariable( "age" , "25" );
GroovyShell shell = new GroovyShell(bind);
Object obj = shell.evaluate( "str = name+age;return str" );
System.out.println(obj);
}
}
3、通過 groovyScriptEngine 執行文件或者腳本,例如:
package groovy_dsl.script;
import groovy.util.GroovyScriptEngine;
public class ScriptEngine {
public static void main(String[] args) throws Exception {
GroovyScriptEngine engine = new GroovyScriptEngine( "" );
Object obj = engine.run( "src/main/java/groovy_dsl/script/script_test.groovy" , "iamzhongyong" );
System.out.println(obj);
}
}
4、通過 GroovyClassLoader 來執行,例如:
package groovy_dsl.classloader;
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyObject;
import java.io.File;
import java.io.IOException;
public class GroovyClassLoaderEx {
public static void main(String[] args) throws Exception, IOException {
GroovyClassLoader loader = new GroovyClassLoader();
for ( int i= 0 ;i< 100 ;i++){
Class<?> clazz = loader.parseClass( new File( "src/main/java/groovy_dsl/classloader/UserDO.groovy" ));
GroovyObject clazzObj = (GroovyObject)clazz.newInstance();
clazzObj.invokeMethod( "setName" , "iamzhongyong" );
clazzObj.invokeMethod( "setSex" , "Boy" );
clazzObj.invokeMethod( "setAge" , "26" );
System.out.println(clazzObj.invokeMethod( "getAllInfo" , null ));
}
}
}
使用groovy尤其需要主要的問題?
通過看groovy的創建類的地方,就能發現,每次執行的時候,都會新生成一個class文件,這樣就會導致JVM的perm區持續增長,進而導致FullGCc問題,解決辦法很簡單,就是腳本文件變化了之後才去創建文件,之前從緩存中獲取即可。
groovy中的源碼如下:
return parseClass(text, "script" + System.currentTimeMillis() + Math.abs(text.hashCode()) + ".groovy" );
這個是增加緩存的代碼:
GroovyClassLoader groovyClassLoader = new GroovyClassLoader(GroovyScriptExecute. class .getClassLoader());
Class<?> groovyClass = null ;
String classKey = String.valueOf(scriptClass.hashCode());
//先從緩存裡面去Class文件
if (GroovyScriptClassCache.newInstance().containsKey(classKey)){
groovyClass = GroovyScriptClassCache.newInstance().getClassByKey(classKey);
} else {
groovyClass = groovyClassLoader.parseClass(scriptClass);
GroovyScriptClassCache.newInstance().putClass(classKey, groovyClass);
}
GroovyObject go = (GroovyObject)groovyClass.newInstance();
下面這個是緩存的單例類,貼一下:
public class GroovyScriptClassCache {
private static final Map<String /*class文件的描述*/ ,Class<?>> GROOVY_SCRIPT_CLASS_CACHE = new HashMap<String,Class<?>>();
private GroovyScriptClassCache(){}
private static GroovyScriptClassCache instance = new GroovyScriptClassCache();
public static GroovyScriptClassCache newInstance(){
return instance;
}
public Class<?> getClassByKey(String key){
return GROOVY_SCRIPT_CLASS_CACHE.get(key);
}
public void putClass(String key,Class<?> clazz){
GROOVY_SCRIPT_CLASS_CACHE.put(key, clazz);
}
public boolean containsKey(String key){
return GROOVY_SCRIPT_CLASS_CACHE.containsKey(key);
}
}
為啥要每次new一個GroovyClassLoader,而不是所有的腳本持有一個?
因為如果腳本重新載入了,這時候就會有新老兩個class文件,如果通過一個classloader持有的話,這樣在GC掃描的時候,會認為老的類還在存活,導致回收不掉,所以每次new一個就能解決這個問題了。
注意CodeCache的設置大小
對於大量使用Groovy的應用,尤其是Groovy腳本還會經常更新的應用,由於這些Groovy腳本在執行了很多次後都會被JVM編譯為native進行優化,會占據一些CodeCache空間,而如果這樣的腳本很多的話,可能會導致CodeCache被用滿,而CodeCache一旦被用滿,JVM的Compiler就會被禁用,那性能下降的就不是一點點了。
Code Cache用滿一方面是因為空間可能不夠用,另一方面是Code Cache是不會回收的,所以會累積的越來越多(其實在不採用groovy這種動態更新/裝載class的情況下的話,是不會太多的),所以解法一可以是增大code cache的size,可通過在啟動參數上增加-XX:ReservedCodeCacheSize=256m(Oracle JVM Team那邊也是把code cache調大的),二是啟用code cache的回收機制(關於Code Cache flushing的具體策略請參見此文),可通過在啟動參數上增加:-XX:+UseCodeCacheFlushing來啟用。