Julia: modul dan impor aliasing

Dibuat pada 5 Sep 2012  ·  96Komentar  ·  Sumber: JuliaLang/julia

Untuk sistem modul, kita dapat mengimpor dan menggunakan modul dengan notasi titik:

import ArgParse
... 
    ArgParse.add_argument(p, "--opt1") 
...

Ini dapat berguna untuk mencegah polusi namespace. Namun, karena nama modul yang bertele-tele, alangkah baiknya jika memiliki alias modul:

import ArgParse as ap 
... 
    ap.add_argument(p, "--opt1") 
...
design modules speculative

Komentar yang paling membantu

masalah ini sudah ada sejak lama, meskipun beberapa ekstensi masih harus dibahas, the

import LongPackage as longpkg

sendiri tampaknya cukup masuk akal.

Semua 96 komentar

Saya menyadari beberapa menit yang lalu bahwa Anda dapat melakukan hal berikut:

import ArgParse
ap = ArgParse

ap.add_argument(...)

Saya masih berpikir akan lebih baik untuk memiliki notasi "import as" sebagai gula sintaksis.

Sementara saya di sini dan memikirkannya, akan menyenangkan juga memiliki cara mengimpor beberapa fungsi tertentu di baris impor yang sama, seperti yang disebutkan dalam posting forum @JeffreySarnoff . Pencarian melalui masalah belum mengungkapkan permintaan seperti itu.

Sesuatu seperti

# from the forum post
import Module.(export1,export2,export3)
# or
import Module.[export1,export2,export3]
# or maybe
import Module.{export1,export2,export3}

Ini masalah yang berbeda dari yang ini, tetapi terkait. Haruskah saya

  1. perbarui masalah ini, atau
  2. buat masalah baru

(Saya berasumsi kegunaan fitur semacam itu tidak kontroversial...)

Sunting : Ini berfungsi sekarang dengan import Module: export1, export2, export3

Saya pikir itu juga harus mendukung mis

import ArgParse.add_argument as addarg

untuk dapat mengganti nama anggota modul saat diimpor.

Ingin tahu bagaimana nama fungsi yang diganti namanya akan berpartisipasi dalam pengiriman?

Itu harus bekerja pada dasarnya seperti alias, setara dengan const foo = Base.bar .

Itu harus bekerja pada dasarnya seperti alias, setara dengan const foo =
Base.bar.

Saat kami mengimpor fungsi, kami berencana untuk menggunakannya atau menimpanya. Diberikan
di atas, dengan

impor Base.bar sebagai foo

kita pasti bisa menggunakan foo sebagai Base.bar, tetapi akan mendefinisikan foo juga menimpa
Basis.bar? Haruskah?

Ini adalah masalah lama, tapi saya pikir ini saatnya untuk meninjau kembali ini karena kita mendekati 0.2

Dalam menulis kode, saya menemukan bahwa saya selalu ingin menulis import NumericExtensions as ne dan akhirnya mengingatkan diri saya bahwa ini belum didukung.

Saya kira ini tidak terlalu sulit untuk diterapkan, dan menurut saya, ini jauh lebih bagus daripada menulis

import NumericExtensions
const ne = NumericExtensions

+1

+1

Apakah ini masih relevan? Saya pribadi tidak keberatan hanya melakukan tambahan foo = Foo untuk modul alias, tapi sepertinya ada beberapa konsensus untuk mendukung aliasing gula. Seseorang yang merasa cukup kuat mungkin harus melakukan PR sendiri.
Namun perhatikan bahwa x as y adalah salah satu pesaing terkuat untuk sintaks convert(y,x) yang disebutkan di #1470. Sepertinya tidak akan terlalu sulit untuk membedakan keduanya, tetapi hanya mencatat.

Nilai dari fitur ini adalah Anda dapat menghindari mengimpor nama asli.

+1
Akan sangat bagus untuk memiliki fitur ini.

+1

Daripada memperkenalkan kata kunci baru as , bagaimana dengan menggunakan operator => , seperti pada

import Tlahuixcalpantecuhtli => Venus: xxxxxxxxx => x9, yyyyyyyy => y8, zzz

Ini secara ortogonal akan memungkinkan aliasing modul dan subset variabel apa pun dalam sintaks yang sama.

Saya tidak tahu, itu tampak sangat jelek bagi saya.

import Tlahuixcalpantecuhtli as Venus: xxxxxxxxx as x9, yyyyyyyy as y8, zzz

Apakah itu lebih baik? Saya merasa jauh lebih tidak mudah dibaca.

Saya pribadi menemukan as lebih jelas daripada => , yang sepertinya bisa berarti banyak hal.

pengungkapan penuh: python bias.

Saya suka sintaks => lebih baik daripada as .

Saya suka gudang sepeda yang terjebak dalam keseimbangan Nash.

Mengapa Anda mengubah simbol bagian dalam modul? Itu jelek karena Anda seharusnya tidak melakukan itu.

Saya suka sintaks impor Haskell . Saya merasa ruang nama Python lebih terperinci daripada modul Julia. Modul Julia lebih semangat dibanding modul haskell, jadi mungkin kita harus mencari inspirasi di sana.

Saya setuju dengan @ssfrr , kata kunci as jauh lebih jelas, dan juga akrab bagi pengguna Python/Haskell. Untuk mengatasi masalah @StefanKarpinski dengan keterbacaan, pendekatan seperti python juga akan membantu:

from Tlahuixcalpantecuhtli as Venus import xxxxxxxxx as x9, yyyyyyyy as y8, zzz

Saya merasa seperti sedang berbicara dengan REPL. Tetapi saya tahu bahwa saran semacam ini tidak mungkin dilakukan.

from Tlahuixcalpantecuhtli as Venus import xxxxxxxxx as x9, yyyyyyyy as y8, zzz

Ini adalah salah satu pilihan sintaksis paling favorit saya di Python. Untuk mengubah arti sedikit Anda harus mengatur ulang seluruh baris secara radikal, mengubah kata kunci awal dan urutan semuanya. Itu terlihat sangat berbeda dari impor lainnya, mengaburkan fakta bahwa mereka melakukan hal yang hampir sama. Ini adalah desain sintaksis yang mengerikan, imo, memberikan terlalu banyak bobot untuk menjadi seperti bahasa Inggris yang dangkal.

:+1: untuk as , :-1: untuk from

import a => b: c => d, e => f terasa agak terlalu aneh bagi saya.

Saya tidak pernah mendengar tentang ekuilibria Nash dan setelah membacanya, saya tidak berpikir ini merupakan keseimbangan. Tapi lucunya, sementara bikeshed ini memiliki 10 tanggapan dalam satu jam, proposal di #6984 yang menurut saya sangat penting (tetapi lebih sulit) telah berjalan 4 jam tanpa komentar!

Adapun as vs. => : keduanya akan menjadi peningkatan yang bagus dari situasi saat ini.

Poin bagus @BobPortmann di #6984.

Saya pikir => bagus untuk ini, FWIW.

Tapi lucunya, sementara bikeshed ini memiliki 10 tanggapan dalam satu jam, proposal di #6984 yang menurut saya sangat penting (tetapi lebih sulit) telah berjalan 4 jam tanpa komentar!

Dalam analogi asli Parkinson, masalah ini adalah gudang sepeda dan # 6984 adalah reaktor nuklir.

:)

Saya tidak suka mengaduk panci ini tapi saya pikir saya lebih suka as . => agak kabur, dan ini aneh untuk berbagi sintaks dengan kamus. Mungkin hanya = masuk akal: import Foo: x = y , dalam analogi dengan const x = Foo.y yang akan Anda lakukan sekarang.

Jika tidak ada yang lain, tabel dalam dokumentasi Haskell sangat membantu. Saya sering (terutama ketika pertama kali belajar julia) bingung kapan harus menggunakan import / using / require , atau kapan harus melakukan import Mod.thing vs import Mod: thing . Saya sebenarnya hanya mencari penjelasan tentang sintaks titik dua pada impor dan tidak dapat menemukannya.

@jakebolewski sepertinya sintaks Haskell cukup dekat, dengan using Julia setara dengan Haskell (tidak memenuhi syarat) import , dan import Julia setara dengan import qualified Haskell


Sebagai titik awal, dapatkah seseorang yang lebih tahu mengonfirmasi bahwa ini adalah ringkasan yang baik dari sintaks impor/penggunaan yang tersedia saat ini? Katakanlah kita memiliki modul Mod yang mengekspor fungsi x dan y , dan juga memiliki fungsi yang tidak diekspor p dan q .

import Mod membawa Mod.x , Mod.y , Mod.p , dan Mod.q . Fungsi yang diimpor semuanya tersedia untuk ekstensi metode

using Mod mendatangkan x , y , Mod.x , Mod.y , Mod.p , dan Mod.q . x dan y tidak tersedia untuk ekstensi metode, tetapi Mod.* tersedia.

import Mod.x, Mod.p mendatangkan x , p , Mod.x , Mod.y , Mod.p , dan Mod.q . Semuanya tersedia untuk ekstensi metode.

import Mod: x, p sama dengan import Mod.x, Mod.p

using Mod.x, Mod.p mendatangkan x , p , Mod.x , Mod.y , Mod.p , dan Mod.q . x dan p tidak tersedia untuk ekstensi metode tetapi Mod.* tersedia.

using Mod: x, p sama dengan using Mod.x, Mod.p

Sejauh yang saya tahu using Mod adalah satu-satunya penggunaan yang peduli dengan apa yang diekspor oleh Mod .

Akan sangat berguna jika ringkasan ini ada di dokumen Modul! Adakah yang bisa mengkonfirmasi ini, jadi saya bisa menyiapkan PR?

Sepertinya versi yang paling tidak kontroversial adalah:

import Tlahuixcalpantecuhtli as Venus: xxxxxxxxx as x9, yyyyyyyy as y8, zzz

Aku keren dengan itu. Versi penugasan menarik, mengujinya:

import Venus = Tlahuixcalpantecuhtli: x9 = xxxxxxxxx, y8 = yyyyyyyy, zzz

Saya pikir saya akan membenci itu, tetapi sebenarnya cukup bagus. Saya suka bahwa nama-nama yang diperkenalkan dalam modul ini didahulukan dan paling menonjol – dalam banyak hal itulah yang terpenting.

@jakebolewski : Mengapa Anda mengganti simbol bagian dalam modul? Itu jelek karena Anda seharusnya tidak melakukan itu.

Anda mungkin ingin mengimpor binding dengan nama yang bentrok dari dua modul berbeda dan ini memungkinkan. Anda juga dapat memenuhi syarat sepenuhnya, tetapi jika kami mendukung aliasing, kami mungkin juga mendukung ini.

Beberapa baris baru yang ditempatkan dengan baik membuat lebih mudah dibaca, IMO:

import Tlahuixcalpantecuhtli as Venus:
    xxxxxxxxx as x9, 
    yyyyyyyy as y8,
    zzz

atau

import Venus = Tlahuixcalpantecuhtli: 
    x9 = xxxxxxxxx, 
    y8 = yyyyyyyy, 
    zzz

Saya menemukan bahwa saya lebih suka versi penugasan cukup kuat. Bagaimanapun, impor adalah bentuk penugasan.

Akan sangat berguna jika ringkasan ini ada di dokumen Modul! Adakah yang bisa mengkonfirmasi ini, jadi saya bisa menyiapkan PR?

@brk00 , lakukanlah!

@kmsquire , saya akan mengerjakannya hari ini!

Tetapi sebelum melakukan itu, saya ingin memastikan bahwa saya memahaminya dengan baik. Dalam contoh @ssfrr , misalkan saya menggunakan REPL dan ketik using Mod . Fungsi yang diimpor x dan y tidak tersedia untuk ekstensi metode. Artinya, jika saya mendeklarasikan fungsi x dan y lainnya, saya tidak akan lagi memiliki akses ke metode Mod yang pernah saya impor, hanya ke metode baru?

Inilah yang terjadi jika Anda mencoba memperluas fungsi tanpa mengimpornya:

julia> module Mod

       export x, y

       x() = "x"
       y() = "y"
       p() = "p"
       q() = "q"

       end

julia> using Mod

julia> x()
"x"

julia> p()
ERROR: p not defined

julia> x(n) = n
ERROR: error in method definition: function Mod.x must be explicitly imported to be extended

Anda dapat menambahkan metode seperti ini:

julia> import Mod: x # or import Mod.x

julia> x(n) = n
x (generic function with 2 methods)

julia> methods(x)
# 2 methods for generic function "x":
x() at none:5
x(n) at none:1

Yah, saya bingung dengan perilaku penyelesaian nama:

julia> module Mod

       export x, y

       x() = "x"
       y() = "y"
       p() = "p"
       q() = "q"

       end

julia> using Mod

julia> x(n) = n
x (generic function with 1 method)

Jika saya menetapkan fungsi baru ke x sebelum _using_ yang baru saja saya impor using Mod , kesalahan tidak akan muncul. Tetapi jika saya, misalnya, memanggil x() sebelum penugasan baru (seperti yang Anda lakukan dalam contoh Anda), kesalahan memang muncul.

Ah, menarik! Aku tidak tahu tentang itu. Saya kebetulan menelepon x untuk mendemonstrasikan penspasian nama setelah using .

Mungkin salah satu pengembang inti dapat menjelaskan. Apa yang terjadi ketika x dipanggil yang memicu kesalahan pada upaya kelebihan beban?

Saya menemukan aliasing yang disarankan oleh @carlobaldassi di atas sangat berguna dalam praktik.

Saya bertanya-tanya apakah import bisa saja mengembalikan objek modul, sehingga bisa alias langsung dengan tugas, dengan atau tanpa const ? Misalnya

const Shortname = import ModuleWithLongName

dari pada

import ModuleWithLongName
const Shortname = ModuleWithLongName

Ini tidak memerlukan sintaks baru, hanya kombinasi elemen sintaks yang ada. Saya menyadari bahwa saat ini import adalah "pernyataan", disebut murni untuk efek samping, dan tidak memiliki nilai. Jika parser tidak mengizinkan ini, saya lebih suka import("Module") atau yang serupa.

Saya pikir opsi untuk modul alias mungkin bagus, tetapi saya juga berpikir bahwa ada kelemahan yang tidak disebutkan siapa pun: itu dapat mengaburkan kode secara signifikan. Dari sudut pandang pembaca kode, bagus untuk hanya memiliki satu nama deskriptif untuk sebuah modul.

Cukup sepele untuk dilihat? Formulir yang dipersingkat kemungkinan juga akan distandarisasi untuk paket populer seperti np untuk numpy .

Saya masih lebih suka numpy untuk standar np dan bahkan Arrays ke numpy . numpy terdengar seperti persilangan antara gerakan dansa tahun 1950-an dan wabah mematikan.

dapat dengan mudah hanya menulis:

Base.require("ArgParse")
const ap = Main.ArgParse

ini tidak memerlukan sintaks untuk 1.0

Saya merasa bahwa kita harus memiliki sintaks untuk ini. Ya, kami dapat hidup tanpanya karena Anda dapat melakukan require dan tugas const , tetapi menggunakan require cukup jelek dan kurangnya sintaks yang nyaman membuat orang enggan mengganti nama sesuatu sesuai keinginan/kebutuhan mereka.

Trik const menjadi mudah gagal ketika seseorang perlu alias makro, ini adalah cara saya melakukannya, dan saya butuh beberapa saat untuk mencari tahu:

julia> macro foo(a, b, c)                                  
           a, b, c                                         
       end                                                 
<strong i="8">@foo</strong> (macro with 1 method)                                 

julia> macro f(args...)                                    
           Expr(:macrocall, Symbol("@foo"), args...) |> esc
       end                                                 
<strong i="9">@f</strong> (macro with 1 method)                                   

julia> <strong i="10">@f</strong> 1 2 3                                            
(1,2,3)                                                    

Di ImportMacros.jl saya menerapkan:

  • <strong i="15">@from</strong> Foo.Bar use foo as f
  • <strong i="18">@from</strong> Foo.Bar use <strong i="19">@foo</strong> as @f

Lihat: https://github.com/fredrikekre/ImportMacros.jl/pull/3

@Ismael-VC

Mencoba

<strong i="7">@eval</strong> const $(Symbol("@foo")) = $(Symbol("@bar"))

yang lebih jelek, tetapi lebih pendek dan mungkin lebih jelas daripada mendefinisikan makro secara lokal

@TotalVerb sekali lagi terima kasih atas bantuan Anda!

Tampaknya satu-satunya fungsi yang hilang dari Julia + ImportMacros adalah untuk alias modul dan campuran aliasing sejumlah variabel objek dari modul tersebut dan mengimpor yang lain tanpa alias:

  • <strong i="9">@from</strong> Foo.Bar as B use foo as f, <strong i="10">@bar</strong> as <strong i="11">@b</strong>, baz

Atau tanpa from :

  • import Foo.Bar as B: foo as f, <strong i="17">@bar</strong> as <strong i="18">@b</strong>, baz
  • import B = Foo.Bar: f = foo, <strong i="21">@b</strong> = <strong i="22">@bar</strong>, baz

Yang terakhir sepertinya tidak mungkin dengan makro:

julia> parse("<strong i="26">@from</strong> Foo.Bar as B use foo as f, <strong i="27">@bar</strong> as <strong i="28">@b</strong>, baz")
:(<strong i="29">@from</strong> Foo.Bar as B use foo as (f,@bar(as,(@b(),baz))))

julia> parse("<strong i="30">@import</strong> Foo.Bar as B: foo as f, <strong i="31">@bar</strong> as <strong i="32">@b</strong>, baz")
:(<strong i="33">@import</strong> Foo.Bar as B:foo as (f,@bar(as,(@b(),baz))))

julia> parse("<strong i="34">@import</strong> B = Foo.Bar: f = foo, <strong i="35">@b</strong> = <strong i="36">@bar</strong>, baz")
ERROR: ParseError("unexpected \"=\"")
 in #parse#310(::Bool, ::Bool, ::Function, ::String, ::Int64) at .\parse.jl:184
 in (::Base.#kw##parse)(::Array{Any,1}, ::Base.#parse, ::String, ::Int64) at .\<missing>:0
 in #parse#311(::Bool, ::Function, ::String) at .\parse.jl:194
 in parse(::String) at .\parse.jl:194

Ini sebenarnya tidak perlu diputuskan untuk 1.0 karena semua sintaks yang diusulkan adalah kesalahan atau omong kosong total.

Apa yang harus terjadi pada alias modul ketika modul asli didefinisikan ulang, misalnya, dengan reload("...") pada REPL? Dengan pendekatan const M = MyModule , M masih merujuk ke modul lama setelah memuat ulang, jadi setiap nama yang baru didefinisikan di MyModule hanya akan dapat diakses oleh MyModule.name tetapi tidak M.name .

Dalam hal ini, sintaks alias harus lebih dari gula sintaksis untuk const M = Module , tetapi pastikan bahwa M selalu mengacu pada hal yang sama dengan MyModule .

Ini juga akan menyederhanakan alur kerja REPL karena saya dapat melanjutkan ke import modul selama pengembangan tetapi dapat merujuknya melalui alias yang lebih pendek tanpa harus membangun kembali alias (non- const ) setiap kali saya reload .

Mulai sekarang, reload telah dihapus sehingga masalah ini tidak berlaku lagi.

Ini juga berlaku untuk include , atau apakah saya melewatkan sesuatu? Secara umum, ketika sebuah modul didefinisikan ulang, nama modul import ed mengacu pada definisi baru sedangkan alias yang ditentukan oleh penugasan mengacu pada definisi lama, bukan?

Tidak, itu seharusnya tidak menjadi perhatian. Nama yang diimpor TIDAK AKAN PERNAH diubah ketika modul didefinisikan ulang, termasuk normal import . Yang berubah adalah modul yang akan diimpor jika Anda mengimpornya lagi. Impor selalu hanya mengikat.

Ok, mungkin saya tidak mengekspresikan diri saya dengan jelas, jadi ini contohnya: Jika Anda membuat file test.jl dengan konten

module Tst
f() = 1
end

anda dapat memuatnya, mengimpor Tst , mendefinisikan alias ke Tst , dan semuanya baik-baik saja:

julia> include("test.jl")
Tst

julia> import Tst

julia> const Tst2 = Tst
Tst

julia> Tst.f()
1

julia> Tst2.f()
1

Jika sekarang Anda mengubah test.jl menjadi

module Tst
f() = 2
end

dan re- include di REPL, modul dan aliasnya berperilaku berbeda:

julia> include("test.jl")
WARNING: replacing module Tst
Tst

julia> Tst.f()
2

julia> Tst2.f()
1

Saya mengerti mengapa ini terjadi, tetapi saya pikir ini seharusnya tidak terjadi ketika Anda membuat alias dengan sesuatu seperti import Tst as Tst2 .

Saya menguji ini pada 0,6.2, dan saat ini saya tidak dapat mengujinya pada 0,7, jadi saya tidak melakukannya sekarang jika ini masih terjadi.

Anda tidak mengimpornya sama sekali. Modul yang Anda sertakan sudah ditentukan dalam cakupan Anda. import adalah larangan.

Benar, tapi bukan ini intinya. Intinya adalah apa yang terjadi ketika saya melakukan sesuatu seperti hipotetis import Tst as Tst2 . Maka pernyataan ini bukan no-op tetapi membuat alias.

Jika alias ini berfungsi seperti const Tst2 = Tst , maka mendefinisikan ulang modul Tst akan membuat alias menunjuk ke versi modul yang lama. Ini tidak diinginkan dalam hal apapun. Alias ​​harus menunjuk ke versi baru Tst juga, atau pengguna harus dipaksa untuk membuat kembali alias. Tetapi dalam kasus terakhir, menggunakan alias lama tanpa membangun kembali itu akan menimbulkan kesalahan alih-alih menunjuk ke modul lama.

Itulah intinya. Masalah ini adalah tentang menambahkan fungsi ke import bukan ke definisi modul. import Anda adalah no-op dan setelah menghapusnya kode Anda tidak memiliki import atau using lagi sehingga tidak terkait dengan masalah ini. Harap ubah agar modul tidak didefinisikan dalam cakupan yang sama dengan import .

import Tst as Tst2 akan bekerja sama dengan import Tst dalam hal apa yang mengikat nama itu, yang selalu mengikat dan bukan keajaiban apa pun yang Anda inginkan. Ini BUKAN tentang menambahkan alias saat mendefinisikan modul.

Dengan kata lain, kode Anda pada dasarnya adalah,

a = Ref(1) # include
a = a # import
b = a # alias
a = Ref(2) # include again

Dan tidak masuk akal untuk mengeluh tentang perilaku b = a karena a tidak diikat oleh a = a sama sekali. Semua yang Anda lihat adalah efek samping dari mendefinisikan modul dalam lingkup yang sama dengan impor (yaitu a = a dan a = Ref(...) dalam lingkup yang sama) dalam contoh yang buruk.

Oke, saya hanya ingin menunjukkan bahwa dalam beberapa situasi, alias yang ditentukan oleh tugas tidak akan berfungsi seperti yang diharapkan. Mungkin saya memilih contoh yang buruk. Saya pikir itu mungkin penting untuk sintaks yang membuat alias modul (apakah terkait dengan import ), tetapi sekarang ini tetap hipotetis. Maaf untuk kebisingan.

masalah ini sudah ada sejak lama, meskipun beberapa ekstensi masih harus dibahas, the

import LongPackage as longpkg

sendiri tampaknya cukup masuk akal.

Menabrak. Saya bertanya-tanya seperti apa solusi terbaik - untuk saat ini -? Inilah yang saya lakukan:

import LinearAlgebra
const linalg = LinearAlgebra

Tolong perbaiki saya jika ada solusi yang lebih baik!

Itu adalah standar saat ini.

Bagaimana dengan sintaks ~? Saya tidak tahu konsekuensinya, tetapi memiliki estetika yang bagus. Juga, ~ digunakan sebagai simbol untuk perkiraan.

import LongPackage ~ lp

@JeffreySarnoff mengutip Stefan

@StefanKarpinski

Ini adalah salah satu pilihan sintaksis paling favorit saya di Python. Untuk mengubah arti sedikit Anda harus mengatur ulang seluruh baris secara radikal, mengubah kata kunci awal dan urutan semuanya. Itu terlihat sangat berbeda dari impor lainnya, mengaburkan fakta bahwa mereka melakukan hal yang hampir sama. Ini adalah desain sintaksis yang mengerikan, imo, memberikan terlalu banyak bobot untuk menjadi seperti bahasa Inggris yang dangkal.

Dalam hal ini, ~ tidak ada hubungannya dengan aspek sintaksis Python yang mirip bahasa Inggris. Saya pikir ketika saya melihat ~, saya hanya mengenali konsep matematika perkiraan. 10.001 ~ 10.

Jadi, dalam pengertian itu, saya menemukan ~ cukup bagus sebenarnya.

import LongPackage ~ lp
import HugePackage ~ hp
import MassivePackage ~ mp
import GiantPackage ~ gp

:-)

ok -- lupakan python -- Saya menghapus komentar itu demi

lp imports LongPlayingRecords
hp imports HewlettPackard
mp imports MilitaryPolice
gp imports PariForNumberTheory

Saya awalnya tidak menyukainya, tetapi begitu banyak orang tampaknya secara alami ingin menulis ini dengan as Saya harus mengatakan bahwa sepertinya tidak pantas untuk melakukan hal lain. Itu tidak harus dicadangkan sebagai kata kunci atau apa pun karena ini adalah konteks sintaksis yang jelas.

Sebuah bahasa pemrograman yang _trys_ agar orang tahu apa artinya !?!

@JeffreySarnoff

Bahasa pemrograman yang mencoba menjadi lebih baik dari Python !!!

@neilpanchal Julia jelas merupakan bahasa yang mencoba menjadi lebih baik daripada Python dalam banyak hal. Di sisi lain, itu cukup jelas tidak keluar dari cara itu untuk menjadi _berbeda_ dari Python di mana Python mendapatkan sesuatu yang benar. Julia meminjam konvensi sintaksis dari kiri dan kanan Python.

Silakan adopsi python as . Mereka melakukannya dengan benar.

julia> impor LightGraphs sebagai lg
KESALAHAN: sintaks: token tambahan "sebagai" setelah akhir ekspresi

Hanya komentar $0,02 lainnya yang mendukung as yang lolos dari Python. fwiw, sekarang saya menggunakan Julia dengan keteraturan lagi, saya melewatkan ini. Tidak seperti di Python, tetapi seperti di Clojure (lihat contoh ), di mana ruang nama lingkup paket (yang bagus untuk disambiguasi) dapat disederhanakan untuk membuat penggunaan perpustakaan secara eksplisit jauh lebih praktis. Karena saya memiliki preferensi untuk menghindari using (yaitu impor wildcard) memiliki beberapa gula sintaksis ke import Gadlfy as gf tanpa penambahan baris const gf = (apa yang saya lakukan saat ini) akan berguna.

Namun komentar lain yang mendukung sintaks as :heart: Saya berharap ini sangat sulit untuk rilis Julia mendatang.

Saya juga berharap ini terjadi. Terutama karena itu bukan perubahan yang melanggar (kan?).

Saya pikir ini akan diimplementasikan di beberapa titik (saya akan mencoba sendiri jika saya bisa meluangkan waktu), tetapi sementara itu, paket ImportMacros memiliki hampir semua fungsi yang diminta di sini (meskipun tidak ada dokumentasi) :

<strong i="8">@import</strong> ModuleA as ma
<strong i="9">@using</strong> ModuleB as mb
<strong i="10">@from</strong> ModuleC use long_function_name as func
<strong i="11">@from</strong> Module use <strong i="12">@macroname</strong> as <strong i="13">@alias</strong>

Saya tidak tahu tentang ImportMacros .jl, terima kasih telah menunjukkannya. Jika fungsi ini ada dalam sebuah paket maka saya rasa tidak begitu penting untuk memilikinya dalam bahasa dasar.

Saya masih berpikir ini akan bagus untuk dimiliki dalam bahasa.

Impor adalah jenis IMO yang hampir _selalu_ ingin Anda tunda ke konvensi bahasa dasar dan tidak membungkus makro atau menambahkan ketergantungan paket. import ... const adalah hal yang lebih baik untuk mundur, bahkan (terutama) jika bahasa dasar tidak pernah diperluas untuk membuat proses dua langkah itu lebih ringkas.

Secara khusus, agak jelek untuk dilihat

using ImportMacros
<strong i="6">@using</strong> OtherPackage as ...
<strong i="7">@using</strong> ThirdPackage as ...

karena using non-makro menonjol.

Bagaimana dengan import mengembalikan modul/fungsi/apa pun yang sebenarnya dibawa ke ruang lingkup?
Kemudian Anda bisa menulis
lg = import LightGraphs
baz = import foo.bar
baz, kit, kat = import foo : bar1, bar2, bar3
Satu-satunya hal yang perlu diubah adalah fungsi impor

Saya sangat menyukai solusi @DhruvaSambrani karena cocok dengan pendekatan "semuanya adalah ekspresi" Julia.

Satu-satunya hal adalah bahwa, agar konsisten, ekspresi impor masih harus membentuk efek samping dari membawa nama lengkap ke dalam ruang lingkup (mungkin bukan bencana). Bisa juga casing khusus untuk tidak mengimpor nama lengkap, tetapi casing khusus itu kotor.

Di OCaml (bahasa dengan modul terbaik!), Anda dapat melakukan sesuatu seperti:

module LG = LightGraphs

Perbedaan penting di sini adalah bahwa nama yang memenuhi syarat dari setiap modul yang dikompilasi dengan program OCaml secara otomatis berada dalam ruang lingkup.

Tentu saja, menggunakan import LightGraphs as LG memiliki manfaat bahwa "semua orang" sudah mengetahuinya dari Python, tetapi selera pribadi saya adalah lebih baik menggunakan kembali sintaks penugasan untuk sesuatu yang secara harfiah adalah penugasan.

Atau perubahan yang lebih luas adalah dengan memperkenalkan "namespace" sebagai Tipe (entah apakah itu sudah selesai). Kemudian import dapat memperluas modul/apa pun menjadi namespace dan mengembalikan namespace. Tetapi ini akan merusak semua kode Julia karena hanya melakukan import mod_name tidak akan membuat namespace mod_name tersedia dalam lingkup global. Jika seseorang entah bagaimana dapat membuat ruang nama mod_name tersedia untuk global saat impor digunakan tanpa penetapan sebelumnya, maka itu tidak menjadi masalah.

Atau cukup tambahkan fungsi baru import_as_ns(mod_name) :: Namespace yang akan menjadi fungsi murni yang mengembalikan semua fungsi/modul dll dalam satu namespace.

itu cocok dengan pendekatan "semuanya adalah ekspresi" Julia

Namun, import dan using spesial karena digunakan hanya untuk efek sampingnya, dan hanya di level atas.

Kebetulan, mengingat bahwa masalah ini telah terbuka untuk waktu yang lama, saya bertanya-tanya apakah triase bersedia untuk meninjau kembali dan membuat keputusan. Saya akan menganjurkan penutupan, karena

  1. import Foo; const Bar = Foo memberikan solusi sempurna ketika pengguna tidak keberatan Foo di namespace,
  2. ImportMacros.jl harus menangani sisanya,
  3. keduanya tampaknya tidak terlalu sering digunakan dalam kode praktis untuk menjamin sintaksis khusus.

Saya akan mengatakan bahwa setelah sekian lama, saya masih merindukan ini (dan saya juga menggunakan ImportMacros dalam kode saya sendiri).

Saya pikir gaya kopi yang Anda tulis mempengaruhi kebutuhan (atau keinginan) untuk ini. Ketika saya menulis ML atau kode ilmiah, saya merasa saya tidak terlalu merindukannya. Ketika saya telah menulis kode lain yang menggunakan sejumlah paket dengan nama panjang adalah ketika saya menemukan saya paling banyak menggunakan ImportMacros.

ImportMacros sudah cukup. Saya hanya setuju dengan komentar bahwa itu tidak terlihat bersih.

Saya juga menantikan hari ketika saya dapat menggunakan autoformatter di editor saya untuk mengurutkan impor saya... tetapi sepertinya tidak tahu apa yang harus dilakukan dengan @using ...

Saya juga setuju dengan @kmsquire bahwa ini bukan masalah besar, dan ImportMacros sudah cukup. Tapi metode apa pun harus didokumentasikan agar tidak muncul lagi.

Meskipun saya masih suka gula m=import Module

Saya tidak bermaksud agar pesan saya menyiratkan bahwa ini bukan masalah besar.

Saya masih lebih suka sintaks untuk ini.

ImportMacros sudah cukup. Saya hanya setuju dengan komentar bahwa itu tidak terlihat bersih.

Saya setuju. Juga untuk:

using ImportMacros
<strong i="8">@using</strong> OtherPackage as ...

Agak menjengkelkan ketika menyajikan bahasa kepada pendatang baru atau pemula pemrograman untuk menjelaskan mengapa skrip yang diberikan dimulai dengan inkonsistensi ini, karena memperumit alur dan menggeser fokus pengajaran.

keduanya tampaknya tidak terlalu sering digunakan dalam kode praktis untuk menjamin sintaks khusus

Alasan mengapa orang tidak banyak menggunakan ImportMacros dalam kode sebenarnya bisa jadi karena tradeoff. Misalnya, saya akan menggunakan import ... as ... hampir setiap saat, tetapi kemungkinan tidak dengan biaya mengimpor paket lain terlebih dahulu untuk melakukannya. Lebih dari ketergantungan tambahan, itu juga berdampak dalam hal "rasa" (dan beberapa orang menyukai kode mereka terlihat ramping (terutama di python atau Julia) ️ , dan ini using/@using memberikan " hacky" hingga pengenalan skrip).

Jadi ya, "ImporMakro sudah cukup". Untuk orang yang benar-benar ingin menggunakannya. Tapi itu masalahnya, itu bukan masalah vital, dan orang bisa bekerja tanpanya. Meskipun demikian, saya sangat yakin bahwa biasanya hal-hal kecil inilah yang membuat sintaksis suatu bahasa melekat, oleh karena itu utas monster ini menambahkan dukungannya ke basis.

Saya pikir import ... as ... adalah gula sintaksis yang pasti sepadan, sangat mudah dimengerti dan dijelaskan, dan sangat berguna dalam bahasa seperti Julia di mana paket cenderung memiliki nama yang agak panjang (jelas, ini penting hanya dengan asumsi bahwa orang tidak ingin melakukan using ... ).

Dan fakta bahwa Python telah mengimplementasikannya terlebih dahulu seharusnya tidak terlalu relevan; Julia harus berusaha untuk memiliki sintaksis terbaik sebelum mencoba menjauhkan diri dari bahasa lain dan/atau menekankan identitasnya sendiri.

Memiliki sintaks untuk ini dan konvensi di sekitar modul populer (saya memikirkan bagaimana selalu import numpy as np dan import matplotlib.pyplot as plt ) juga akan memberikan alternatif ringkas untuk melakukan using SuchAndSuch dan mengandalkan export nama ed (yang biasanya saya hindari dalam kode "perpustakaan").

@DominiqueMakowski :

menyajikan bahasa kepada pendatang baru atau pemula pemrograman untuk menjelaskan mengapa skrip yang diberikan dimulai dengan inkonsistensi ini

Saya tidak mengerti mengapa menurut Anda ini adalah inkonsistensi, itu hanyalah manajemen namespace, yang merupakan bagian normal dari pemrograman secara umum.

Juga, mengganti nama modul mungkin bukan sesuatu yang akan ditemui oleh pendatang baru di Julia terlebih dahulu.

Saya tidak mengatakan bahwa tidak ada kasus penggunaan, tetapi mungkin jarang untuk membenarkan kata kuncinya sendiri. Saat ini, mencari using ImportMacros memberikan <10 hasil unik di Github.

Saya akan menggunakan import ... as ... hampir setiap saat, tetapi kemungkinan tidak dengan biaya mengimpor paket lain terlebih dahulu untuk melakukannya

Ini memotong dua arah: jika biaya (sangat kecil) menggunakan paket ringan seperti ImportMacros atau simbol tambahan ( import LongFoo; const Foo = LongFoo ) tidak sebanding dengan manfaatnya, maka manfaatnya mungkin tidak terlalu besar .

Julia harus berusaha untuk memiliki sintaksis terbaik sebelum mencoba menjauhkan diri dari bahasa lain dan/atau menekankan identitasnya sendiri.

Saya tidak yakin mengapa menurut Anda ini adalah motivasi dalam diskusi ini.

Ada beberapa kasus di mana Anda mungkin ingin menggunakan as di mana tugas const tidak berfungsi:

julia> using Distributed

julia> import Future; const future = Future
Future

julia> Future === Distributed.Future # oops, this is what we wanted
false

julia> Future === future # not what we wanted `Future` to mean
true

Ya, Anda bisa menyiasatinya, tapi ini canggung. Mengingat bahwa ini sering berguna, terkadang dibutuhkan dan bahwa import FooBar as FB adalah sintaks "paling tidak mengejutkan" yang disepakati secara umum, sepertinya itulah yang harus kita gunakan. Semua ini membutuhkan seseorang untuk membuat PR yang mengimplementasikannya.

Pengguna Julia baru di sini.
Saya sebagian besar berasal dari latar belakang R, menggunakan Python juga. Saya memiliki pengalaman buruk dengan ruang nama umum paket yang mengarah ke mekanisme pemuatan seperti using . Risiko tabrakan adalah satu, tetapi hanya dari perspektif keterbacaan, mereka adalah beban mental untuk terus-menerus memikirkan modul setiap metode.

Saya tidak tahu seberapa rumit menambahkan sintaks ini? Apakah bisa dilakukan untuk pemula?

Mungkin tidak terlalu mudah. Ini akan melibatkan peretasan kode parser yang ditulis dalam Skema dan menghubungkan perubahan melalui AST, berpotensi menyentuh beberapa kode C juga.

Ini akan menjadi fitur yang bagus untuk menghindari konflik nama fungsi di banyak modul.

Dari diskusi tentang slack, saya menambahkan beberapa pemikiran

Saya ingin tahu apakah ini akan membuat orang kurang berhati-hati dalam memilih nama fungsi dan menambahkan metode dengan benar ke fungsi yang benar. Fakta bahwa, misalnya,

numpy.sin
sympy.sin

adalah fungsi yang berbeda adalah cara yang pasti karena harus mengimplementasikan dua versi fungsi Anda jika Anda ingin berfungsi untuk input numerik dan simbolis. Jika penspasian nama seperti itu menyebar luas di julia juga karena kenyamanan, kita mungkin kehilangan banyak penggunaan kembali kode? Yaitu, saya khawatir ini akan memberi kita lebih sedikit " Ini mendorong orang untuk bekerja sama " seperti yang dikemukakan oleh Lyndon di https://www.oxinabox.net/2020/02/09/whycompositionaljulia.html

@baggepinnen Saya tidak berpikir ini mengubah apa pun dalam hal itu.

Di Julia, metode yang diimplementasikan dalam modul yang berbeda tidak digabungkan dengan mengimpor kedua metode ke dalam namespace yang sama.

julia> module Foo
           export sin
           sin(s::String) = uppercase(s)
       end
Main.Foo

julia> sin(1)
0.8414709848078965

julia> using .Foo
WARNING: using Foo.sin in module Main conflicts with an existing identifier.

julia> sin("wat")
ERROR: MethodError: no method matching sin(::String)
Closest candidates are:
  sin(::BigFloat) at mpfr.jl:727
  sin(::Missing) at math.jl:1197
  sin(::Complex{Float16}) at math.jl:1145
  ...
Stacktrace:
 [1] top-level scope at REPL[4]:1
 [2] run_repl(::REPL.AbstractREPL, ::Any) at /build/julia/src/julia-1.5.1/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:288

julia> Foo.sin("wat")
"WAT"

Seseorang harus secara eksplisit menambahkan pengiriman ke fungsi asli agar ini berfungsi:

julia> Base.sin(s::String) = Foo.sin(s)

julia> sin("wat")
"WAT"

Sejauh yang saya tahu, tidak ada cara yang mungkin untuk modul aliasing untuk mengubah cara fungsi dikirim.

Dan sejujurnya, beberapa fungsi dengan nama yang sama _should_ tinggal di ruang nama yang terpisah. Fungsi find_delta di pustaka numerik akan melakukan sesuatu yang tidak terkait dengan find_delta di pustaka diff file. Setelah kode Anda sangat polimorfik sehingga akan menemukan cara untuk mengeksekusi pada input yang rusak, Anda masuk ke wilayah JavaScript, dan tidak ada yang menginginkannya.

@ninjaaron Saya mungkin gagal menyampaikan beberapa nuansa dalam kekhawatiran saya di atas. Saya tidak peduli dengan perubahan ini yang mengubah apa pun selain strategi yang dipilih orang ketika mereka mengimplementasikan perpustakaan.
Orang yang menerapkan Foo menemui peringatan seperti

julia> using .Foo
WARNING: using Foo.sin in module Main conflicts with an existing identifier.

dapat memilih untuk import .Foo.sin as sin2 , atau memikirkan apakah dia benar-benar ingin memberikan pengiriman baru untuk Base.sin . Maksud saya adalah jika menjadi sangat mudah untuk menganggapnya sebagai fungsi yang berbeda, mungkin ini akan menjadi terlalu luas, bahkan dalam situasi ketika mereka seharusnya menjadi metode yang berbeda dari fungsi yang sama. Situasi saat ini, di mana sedikit lebih canggung untuk berurusan dengan fungsi yang berbeda dengan nama yang sama memiliki efek samping yang baik bahwa orang berbicara satu sama lain dan melakukan yang terbaik untuk mencari tahu apakah itu benar-benar fungsi yang sama atau tidak. Saya tidak menentang kemungkinan untuk memiliki fungsi yang berbeda dengan nama yang sama, yang tentu saja bisa sangat berguna. Saya bahkan tidak yakin apakah kekhawatiran saya penting atau tidak, tetapi saya pikir itu layak untuk mengangkatnya untuk memastikan itu telah dipertimbangkan.

@baggepinnen Itu masuk akal, dan tidak ada salahnya mengungkitnya. Saya tidak berpikir ini akan membuat perbedaan besar bagi orang yang membuat perpustakaan, karena modul aliasing hanya akan mempengaruhi pengguna perpustakaan. Saya kira mungkin bahwa memiliki aliasing modul yang lebih mudah akan menghasilkan lebih sedikit pengguna _mengeluh_ tentang konflik penamaan, tetapi saya akan terkejut jika itu memiliki dampak yang luar biasa pada API.

Ketika saya menulis perpustakaan, saya biasanya cukup sadar apakah saya ingin menambahkan pengiriman ke fungsi di Base atau saya ingin memisahkannya. Saya akan menganggap sebagian besar penulis perpustakaan lainnya juga.

@ninjaaron Saya pikir jika konvensi saat ini menggunakan implementasi khusus untuk pengiriman seperti

numpy.sin
sympy.sin

menggunakan import numpy.sin as np_sin sebagai opsi tambahan untuk pengguna/pengembang tidak akan memengaruhi basis kode saat ini.
Satu-satunya kekhawatiran hanya akan memengaruhi fungsi/antarmuka yang terpapar.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat