Pertahankan API vs. menggunakan idiom di port

12

Saya sedang mengerjakan port dari Python ke Rust dan berlari ke beberapa kode yang tidak bisa diekspresikan secara alami di Rust seperti yang mereka bisa di Python.

Salah satu kasusnya adalah menggunakan parameter default:

class Foo:
  def __init__(self, a="Hello"):
    self._a = a

Di Rust, Anda dapat menerapkan ini menggunakan pembangun:

struct FooBuilder {
  a: &'static str,
}

struct Foo {
  _a: &'static str
}

impl FooBuilder {
  fn new() -> FooBuilder {
    FooBuilder {
      a: "Hello",
    }
  }

  fn change_a(self, new_a: &'static str) -> FooBuilder {
    FooBuilder {
      a: new_a,
      ..self
    }
  }

  fn build(self) -> Foo {
    Foo {
      _a: self.a,
    }
  }
}

Untuk menggunakan kelas dengan Python, cukup:

foo = Foo("Hello, World!")

Namun, di Rust, Anda perlu menulis sesuatu seperti:

let foo = FooBuilder::new().change_a("Hello, World!").build();

Ini mengarah pada pertanyaan: apakah lebih baik memelihara API untuk porta, atau lebih baik menggunakan idiom bahasa porting? Apakah ini tergantung pada seberapa terkenal API untuk memulai?

erip
sumber
2
API kelas adalah bagaimana Anda menggunakannya, bukan bagaimana itu dinyatakan dalam kode. Jadi, terjemahan itu memiliki ABI yang sangat berbeda dan tidak dapat diterima rumit.
Deduplicator
Di mana dikatakan bahwa itu Rust idiomatik?
Nadir Sampaoli
Maaf, saya pasti salah paham. Anda memposting beberapa kode Rust, bersama dengan dilema: cuaca Anda akan mempertahankan API untuk port atau Anda akan menggunakan idiom bahasa porting . Kode itu tidak terlihat seperti salah satu dari kasus-kasus itu. Jika ini adalah interpretasi yang benar, apa tujuan dari contoh kode itu? Apa yang digambarkan dan bagaimana hubungannya dengan pertanyaan aktual?
Nadir Sampaoli

Jawaban:

18

Anda ingin ide-ide Anda diungkapkan dengan jelas dalam bahasa yang menampungnya. Itu berarti menggunakan idiom bahasa host.

Ambil perpustakaan Underscore yang populer: js dan lua . Port lua secara fungsional setara untuk sebagian besar . Tetapi ketika itu tepat, implementasi sedikit berbeda. Sebagai contoh:

_.toArray()

menjadi

_.to_array()

Perubahan ini membuat nama fungsi terasa lebih asli bagi programmer Lua.

Demikian juga, _.each () membutuhkan objek, array, atau sesuatu yang mirip array di JavaScript, tetapi _.each () di Lua juga dapat menggunakan iterator - mekanisme yang tidak tersedia di JavaScript ketika pustaka Underscore asli telah dibuat.

Lua Penulis bijaksana diterjemahkan apa yang penulis asli akan ditujukan jika mereka telah menulis di Lua. Itulah kuncinya. Bertanyalah pada diri sendiri tentang maksud asli dan kemudian terapkan niat itu dalam bahasa pilihan Anda - idiom dan semuanya. Bergantung pada sumber dan bahasa target, ini bisa berarti menambah, mengedit, atau menghapus fitur.

Ingat bahwa pengguna lintas bahasa akan jarang. Sebagian besar pengguna akan menggunakan satu bahasa atau yang lain. Bagi mereka, perbedaan itu tidak masalah. Jika seseorang menggunakan keduanya, mereka mungkin cukup canggih untuk menghargai terjemahan Anda. Tidak ada bedanya dengan menerjemahkan bahasa yang diucapkan. Beberapa ide tidak langsung diterjemahkan. Penerjemah terbaik tetap berpegang pada maksud dari terjemahan aslinya, bukan terjemahan harfiah kata demi kata.

Hanya sedikit Roger
sumber