簡體   English   中英

除了D還有其他語言有靜態嗎?

[英]Are there other languages besides D with static if?

我認為D是static if是一個有趣的語言特征。 這提示了我的問題:是否還有編譯語言的其他示例,其中編譯器具有強大的代碼概念,並且有語言工具可以訪問它們?

例如,此代碼提供類似於Python的repr

char[] repr(T)(T value) {
  static if (is(typeof(value.__repr__))) { // class T provides a "repr()" method
    return value.__repr__();  
  } else static if (is(T:string)) {
    return `"` ~ value ~ `"`;
  // ...other cases...
  } else {
    return toString(value);
  }
}

我認為這很酷,因為它允許一種不同的,更通用的方法來實現重載,這是一種讓代碼更加動態的內部方式,與這樣的功能相比。 例如,編譯器知道我的類有多少字段,但是在大多數語言中,我的代碼無法在編譯時訪問該信息。

CAVEAT:最后一段中有意見,但我只是想為我的問題提供一些動力和澄清,而不是引起爭議。 我只是想知道是否有其他編譯語言有這樣的功能。

任何具有真實宏的語言都具有靜態if的形式。 例如,Lisp和Nemerle允許您使用編程結構(如'if'和for-loops)構建宏擴展的代碼。 這些本質上是編譯時的決定,讓你做類似於static的事情。 在Nemerle宏的情況下,宏基本上是編譯器在編譯時執行的插件。

在C ++中有一個boost MPL庫, 如果可以用來在兩種類型之間進行選擇,它有一種靜態 你可以將一些代碼放在run()成員中的兩種類型中,並獲得類似的東西,但語法非常繁瑣。

例如,使用Boost MPL,您可以執行以下操作:

struct float_impl { 
    static void run() { /* float case code */ }
}
struct int_impl { 
    static void run() { /* int case code */ }
}

typedef typename if_<
          is_same<T, float>
        , float_impl
        , int_impl
        >::type impl_t;
impl_t::run();

在D中,它是:

static if(is(T == float)) {
     /* float code */
}
else {
     /* int code */
}

static_if已被提議用於下一版本的C ++(C ++ 1y)。 它最初是為C ++ 11提出的,但顯然是推遲了。

此處查看提案。 有趣的是,其中一位作者是D.的創造者Walter Bright。

此外, 可以使用編譯器黑客偽造static-if in current C ++

對於“語言的代碼意識”,我沒有看到過比Lisp及其宏設施更好的東西 - 特別是Common Lisp。 但是,在大多數情況下,交易是在編譯時或宏擴展時不知道對象的類型。 對於文字,類型是已知的,因此您可以找到攻擊性宏的示例,以測試對象是否為文字,如果是,則以一種方式對待它 - 可能基於其類型 - 並以其他方式准備檢測到的變量用於運行時類型檢查。

下面是我從CLLIB庫(的一部分改編為例CLOCC幾年前庫)。 目標是提供一些函數,這些函數將使用匹配的前綴從一些其他字符串中刪除前綴字符串。 前綴可以在宏擴展時知道,也可以不知道。 如果是,我們可以進行優化:首先計算前綴的長度並將其作為文字嵌入,這樣在每次調用生成的函數時都不會重新計算它。 該宏一開始令人生畏,但實際生成的代碼很小。

(defmacro after-prefix-core (comparison-op prefix string &optional length)
  "Similar to cllib:string-beg-with-cs."
  (flet ((chop (prefix prefix-length string string-length)
           `(when (and (>= ,string-length ,prefix-length)
                       (,comparison-op ,prefix ,string :end2 ,prefix-length))
              (subseq ,string ,prefix-length ,string-length))))
    (let* ((gstring (gensym "STRING-"))
           (gstring-length (gensym "STRING-LENGTH-")))
      `(let* ((,gstring ,string)
              (,gstring-length ,(or length `(length ,gstring))))
         ,(if (stringp prefix)
              ;; Constant -- length known at expansion time.
              (let ((prefix-length (length prefix)))
                (chop prefix prefix-length gstring gstring-length))
              ;; Other form -- length not known at expansion time.
              (let ((gprefix (gensym "PREFIX-"))
                    (gprefix-length (gensym "PREFIX-LENGTH-")))
                `(let* ((,gprefix ,prefix)
                        (,gprefix-length (length ,gprefix)))
                   ,(chop gprefix gprefix-length gstring gstring-length))))))))


(defmacro after-prefix (prefix string &optional length)
  "Similar to cllib:string-beg-with."
  `(after-prefix-core string-equal ,prefix ,string ,length))


(defmacro after-prefix-cs (prefix string &optional length)
  "Similar to cllib:string-beg-with-cs."
  `(after-prefix-core string= ,prefix ,string ,length))

見表格

(if (stringp prefix)

在中間? 那是在宏擴展時檢查第一個參數,並且根據參數是文字還是符號,其類型可能是也可能不知道。 如果類型是符號,我們假設我們應該等到運行時間重新考慮它作為指向其他值的變量。

這是表單的擴展(after-prefix foo bar)

(LET* ((#:STRING-5340 BAR) (#:STRING-LENGTH-5341 (LENGTH #:STRING-5340)))
  (LET* ((#:PREFIX-5342 FOO) (#:PREFIX-LENGTH-5343 (LENGTH #:PREFIX-5342)))
    (WHEN
        (AND (>= #:STRING-LENGTH-5341 #:PREFIX-LENGTH-5343)
             (STRING-EQUAL #:PREFIX-5342 #:STRING-5340 :END2 #:PREFIX-LENGTH-5343))
      (SUBSEQ #:STRING-5340 #:PREFIX-LENGTH-5343 #:STRING-LENGTH-5341))))

請注意,變量#:PREFIX-LENGTH-5343綁定到FOO計算長度 ,此處綁定到變量#:PREFIX-5342

現在看一下表單的擴展(after-prefix "foo" bar) ,其中前綴現在是一個字符串文字:

(LET* ((#:STRING-5463 BAR) (#:STRING-LENGTH-5464 (LENGTH #:STRING-5463)))
  (WHEN (AND (>= #:STRING-LENGTH-5464 3) (STRING-EQUAL "foo" #:STRING-5463 :END2 3))
    (SUBSEQ #:STRING-5463 3 #:STRING-LENGTH-5464)))

現在沒有計算“foo”的長度; 它的內聯為3。

在這個例子中看起來似乎太多了,但是正如你的問題所說的那樣,能夠做這些事情是一種很好的力量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM