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")
...
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
(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
import Foo; const Bar = Foo
memberikan solusi sempurna ketika pengguna tidak keberatan Foo
di namespace,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.
Komentar yang paling membantu
masalah ini sudah ada sejak lama, meskipun beberapa ekstensi masih harus dibahas, the
sendiri tampaknya cukup masuk akal.