Julia: قم بإزالة الطلب والاستيراد وربما الاستيراد والدمج في استخدام

تم إنشاؤها على ١٤ أغسطس ٢٠١٤  ·  72تعليقات  ·  مصدر: JuliaLang/julia

من القائمة البريدية:

ستيفان:

أعتقد أنه يجب علينا التخلص من الاستيراد تمامًا وفقط

باستخدام Foo
باستخدام Foo: bar

الأول يتم تحميل وإنشاء ارتباط لـ Foo ، وجعل عمليات التصدير متاحة كارتباطات "ناعمة" (ما يفعله الاستخدام الآن). يمكن أيضًا تحميل الملف الثاني وإنشاء ارتباط لـ Foo ، وإتاحة الشريط كربط "صلب" (ما يفعله الاستيراد الآن). "

يبدو أن هذا لا يزال يمثل نقطة ارتباك للوافدين الجدد.

breaking design modules speculative

التعليق الأكثر فائدة

يعجبني التماثل بين import و export . (كما أشار أحدهم في مكان ما.)

ال 72 كومينتر

سنحتاج أيضًا إلى وظيفة import Foo بطريقة ما ، حيث تحصل على Foo ولا شيء آخر

using Foo: ؟

using Foo: Foo ؟

لربط Foo بوحدة Foo (ولا شيء آخر):
import Foo
لربط Foo بالوحدة Foo ، x بـ Foo.x ، y بـ Foo.y
import Foo: x, y
لربط Foo بالوحدة النمطية Foo ، وجميع أسماء Foo المصدرة غير مؤهلة:
import Foo: *

قد يكون هذا using بدلاً من ذلك ، لكنني أشعر أن هذا أكثر بروح import .

يؤدي هذا أيضًا إلى إزالة التمييز بين إدخال شيء ما في النطاق وإتاحته لتمديد الطريقة. أنا شخصياً أعتقد أن هذا أمر جيد ويجعل نظام الوحدات أكثر قابلية للفهم ، لكنني أردت التأكد من أننا طرحناه.

هناك حجة قوية يجب تقديمها وهي أن البنية التي تجعل جميع الارتباطات المصدرة للوحدة النمطية متاحة يجب أن تجعلها ارتباطات ناعمة ( using ) ارتباطات وليست صلبة ( importall ) روابط. افترض أن الوحدة "أ" تستخدم الوحدة "ب" وتعرف foo(::Any) . إذا قام إصدار لاحق من الوحدة "ب" بتعريف وتصدير foo(::Any) ، فأنت لا تريد أن يتشابك كل منهما مع الآخر. لا تريد أيضًا أن تحدد الوحدة "ب" foo(::Int) وأن يكون لديك الوحدة "أ" أحيانًا تستدعي هذه الطريقة بدلاً من الطريقة التي حددتها لأنها أكثر تحديدًا ، أو أن تضطر إلى سرد كافة المعرفات التي تريدها من الوحدة "ب" لتجنب استيراد معرف واحد متضارب.

ولكن إذا كنت قد أدرجت بشكل صريح المعرفات التي تريد استيرادها ، فلن يكون هناك أبدًا سبب لتقديم ربط ناعم. إما أنك لن تحدد طرقًا جديدة للمعرف ، وفي هذه الحالة يكون للارتباطات الصلبة والناعمة سلوكًا متطابقًا ، أو أنك ستحدد طرقًا جديدة لها ، وفي هذه الحالة يكون الربط الناعم معادلاً لعدم الربط وإذا كنت تريد هذا السلوك يجب عليك فقط إزالة المعرف من القائمة.

لذا ، باختصار ، أحب اقتراح StefanKarpinski . من الناحية المفاهيمية ، نحتاج إلى روابط صلبة وناعمة ، ولكن يمكننا الحصول على جميع السلوكيات المفيدة باستخدام كلمة رئيسية واحدة.

أرى وجهة نظرك. في هذه الحالة ، أحب اقتراحك بأن using Foo: (مع النقطتين ولكن بدون عناصر) يبدو متسقًا من الناحية المفاهيمية. تشير النقطتان إلى أنك ستحد من الرموز التي يجب سحبها ، لكنك لا تسرد أيًا منها.

يبدو الزائدة الفارغة : مضحكة بعض الشيء ، لكنني أعتقد أن الناس سيعتادون عليها

تكمن مشكلة علامة النقطتين اللاحقة الفارغة في أننا نبحث حاليًا عن اسم في السطر التالي - وبعبارة أخرى ، فإن using Foo: يعتبر غير مكتمل.

ذات صلة: # 4600

أعلم أن ممارسة Julia الحالية تتمثل في استيراد كل شيء إلى ملف
مساحة الوحدة النمطية الحالية ، لكنني أعتقد حقًا أنه لا يزال هناك
طريقة بسيطة وطبيعية لاستيراد اسم الوحدة فقط.

أعتقد أيضًا أن التحميل الزائد الحالي لاستخدام Foo واستخدام Foo.Bar هو
إشكالية. يبدو داخل Foo ولكن ليس داخل Foo.Bar (ما لم يكن Foo.Bar
وحدة؟)

أعتقد أنه تم تناول هذا الأمر في اقتراح ستيفان

باستخدام Foo: Foo

في يوم الخميس ، 14 أغسطس 2014 ، كتب toivoh [email protected] :

أعلم أن ممارسة Julia الحالية تتمثل في استيراد كل شيء إلى ملف
مساحة الوحدة النمطية الحالية ، لكنني أعتقد حقًا أنه لا يزال هناك
طريقة بسيطة وطبيعية لاستيراد اسم الوحدة فقط.

أعتقد أيضًا أن التحميل الزائد الحالي لاستخدام Foo واستخدام Foo.Bar هو
إشكالية. يبدو داخل Foo ولكن ليس داخل Foo.Bar (ما لم يكن Foo.Bar
وحدة؟)

-
قم بالرد على هذا البريد الإلكتروني مباشرة أو قم بعرضه على GitHub
https://github.com/JuliaLang/julia/issues/8000#issuecomment -52202142.

kmsquire ولكن ماذا يحدث إذا كانت هناك وحدة Foo داخل وحدة Foo؟ هذا أمر غامض للأسف.

هذا خطأ في التصميم (ويسبب تحذيرًا) ، لذلك لا يهم

تعجبني النسخة التي اقترحها ssfrr فوق الأفضل.

هل هناك اصطلاح أساسي بأن الحزم لها نقطة دخول وحدة واحدة فقط؟ - إلى import Foo يعني استيراد وحدة Foo من الحزمة Foo . يجب أن تكون أي وحدة نمطية أخرى وحدة فرعية من Foo . مما يعني أن هناك مراسلات ضمنية بين الحزمة Foo و Foo.jl في العبوة و module Foo بداخلها.

أطلب b / c وأتساءل عما إذا كان يمكن أيضًا استخدام import للاستيراد المحلي / النسبي. لنفترض أن المشروع به src/foo.jl و src/bar.jl ثم في foo.jl :

import bar

سوف يستورد من src/bar.jl . يعد هذا تحسينًا عن استخدام include لأنه يعمل ضمن نظام الوحدة.

نعم ، من المتوقع أن تكون الحزم ونقاط دخول الحزم والوحدات النمطية فردية. يمكنك كسر هذا الاصطلاح إذا احتجت إلى ذلك ، ولكن ليست هناك حاجة ماسة لذلك نظرًا لأن الوحدات النمطية مخصصة فقط للتسمية وليست وحدات وظيفية. الفكرة التي تطرحها هي # 4600 باستثناء بناء الجملة للاستيراد النسبي هو import .bar بينما import bar هو استيراد مطلق.

StefanKarpinski هل يبحث import .bar بالفعل عن "bar.jl" في الدليل المحلي؟ كان لدي انطباع بأن import .Bar أشار فقط إلى وحدة فرعية من الوحدة الرئيسية الحالية بالفعل.

تحديث: هذا ما تقترحه في # 4600. آسف.

: +1 :. إذا كنا سنفعل هذا ، فسيكون 0.4 هو الوقت المناسب للقيام بذلك.

: +1: الرجاء المضي قدمًا وتنظيف بعض من هذا (مقابل 0.4!)

بدلاً من وجود آليتين للاستيراد للتمييز بين التمديد أو عدم التمديد ، فلماذا لا يتم تمديد الإشارة في موقع الامتداد نفسه عبر كلمة رئيسية أو تعليق توضيحي في تعريف الوظيفة ، على سبيل المثال تجاوز الكلمة الأساسية قبل الوظيفة؟ مماثل للتعليق التوضيحي @Override في Java.

هذا له ميزة أن المرء يرى بوضوح أن الوظيفة تتجاوز الأخرى (وبالتالي فهي طريقة)

هذا ممكن بالفعل ،ssagaert. يمكنك القيام بذلك عن طريق كتابة اسم الوحدة بشكل صريح في تعريف الوظيفة (على سبيل المثال ، Base.print(…) = … ) ، ويبدو أنه نمط يتقارب عليه الكثير من الأشخاص. النقطة الشائكة الوحيدة هي أن بناء الجملة لا يعمل مع جميع الأسماء المحتملة (مثل .+ ، إلخ).

(جانبا ، يرجى توخي الحذر لإرفاق وحدات الماكرو مع backticks `` لمنع مضايقة مستخدمي GitHub الآخرين).

: +1: إلى اقتراح ssagaert باستخدام @override ، تظهر رسالة الخطأ الأصلية عندما يحاول المرء تمديد طريقة دون استيرادها أولاً كما يلي:

ERROR: error in method definition: function Foo.x must be explicitly imported to be extended

لذا فربما يكون @extend أكثر ملاءمة؟ أنا لست متحدثًا أصليًا للغة الإنجليزية ، لكن ما أفهمه هو أن _override_ تعني شيئًا مثل: الإلغاء ، أو الإبطال ، أو الإبطال ، أو النفي ، أو الإلغاء ، أو الإلغاء ، أو التوقف ، وما إلى ذلك.

أعتقد أن هذا أكثر وضوحا:

<strong i="13">@extend</strong> Base.show(...) = ...

من:

import Base: show

# ... several lines here

Base.show(...) = ...

@ Ismael-VC Base.show(...) = ... يعمل بالفعل بدون استيراد أي شيء. import ضروري فقط إذا كنت تريد show(...) = ... لتوسيع Base.show .

كانت كلمة تجاوز @ Ismael-VC مجرد اقتراح. يمكن أن تكون ممتدة أو أي شيء آخر ذي معنى. أيضًا يجب ألا يكون هناك @ منذ ذلك الحين في جوليا وهذا يعني أنه ماكرو ( @Override يشير إلى Java حيث يكون تعليقًا توضيحيًا).

simonster شكرا لم أكن أعرف ذلك!

ssagaert لذا تقصد كلمة أساسية؟ لقد جربت شيئًا كهذا ولكني ما زلت أمتلك الماكرو فو:

module Extend

export <strong i="9">@extend</strong>


macro extend(x)
    mod = x.args[1].args[1].args[1]
    met = x.args[1].args[1].args[2]
    imp = :(Expr(:import, $mod, $met))
    :(Expr(:toplevel, $imp, $(esc(x))))
end


end

أعلم أن هذا ليس عامًا ، ما زلت لا أستطيع عمل تعبير يعيد ما يفعله التحليل:

julia> using Extend

julia> type Foo end

julia> <strong i="13">@extend</strong> Base.show(x::Foo) = Foo
:($(Expr(:toplevel, :($(Expr(:import, Base, :show))), show)))

julia> parse("import Base.show; Base.show(x::Foo) = Foo")
:($(Expr(:toplevel, :($(Expr(:import, :Base, :show))), :(Base.show(x::Foo) = begin  # none, line 1:
            Foo
        end))))

أعتقد أن الماكرو العام والعملي @extend لن يغير دلالات آلية الاستيراد.

@ Ismael-VC لقد فعلت ولكني أحب "خدعة" mbauman أيضًا.

أعتقد أنه قد يكون من الجيد أن تكون قادرًا على استخدام . على أنها تعني "هذا". حتى تتمكن من كتابة تعبيرات مثل:
import Base: . (بمعنى استيراد Base.Base )
أو
using ..

أنا متأكد من أن ذلك سيتطلب https://github.com/JuliaLang/julia/pull/11891#issuecomment -116098481. ربما يكفي السماح بمسافات قبل . ، لكن ليس بعده ، لحل حالة الغموض؟

أعتقد أن الطلب قد تم إهماله بالفعل. قد يكون من الجيد إضافة تدوين نقطي أكثر مرونة عند استيراد الوحدة بمقدار 1.0 ، لكنني أشك في أننا سنغير أي شيء هنا من خلال تجميد ميزة 0.6

بعد مجموعة من المناقشات حول هذا أمس ، أميل إلى شيء مثل المقترحات في https://github.com/JuliaLang/julia/issues/8000#issuecomment -52142845 و https://github.com/JuliaLang/julia/ القضايا / 8000 # issuecomment -52143609:

using A: x, y    # hard imports x and y from A

using A: A       # hard imports just the identifier `A`

using A: ...     # soft imports all of A's exports

using A     # equivalent to `using A: A, ...`

using A.B   # A.B must be a module. equivalent to `using A.B: B, ...`

using A: ..., thing1, thing2    # import all exports plus some non-exported things

قد يكون البديل هو الاحتفاظ بـ import بدلاً من using :

import A             # hard binding for the module `A`
import A: ...        # soft bindings for all names exported by `A`
import A: x, y       # hard bindings for `x` and `y` from `A`
import A: x, y, ...  # equivalent to doing both of the previous two

إن القاعدة العامة التي تحدد ما إذا كان الربط صعبًا أم ناعمًا ستكون بسيطة: أي اسم مطلوب صراحةً يكون ارتباطًا صعبًا ، وأي ارتباط يتم توفيره ضمنيًا يكون ناعمًا.

تحرير: هناك بعض الرغبة في إضافة بعض الاختصارات إلى هذا المخطط لـ import A; import A: ... وهو تقريبًا ما يفعله حاليًا using A (الاختلاف الوحيد هو أن using A يستورد حاليًا A ) ؛ يمكن أن يستمر هذا إما using A أو import A... تم اقتراحه.

نعم ، أعتقد أن هذا أيضًا اقتراح جيد. يعود الأمر بشكل أساسي إلى ما إذا كان المرء يفضل using أو import .

ملحق ، يمكننا الاحتفاظ بـ using A كاختصار لـ import A; import A: ... - إلى جانب التخلص من السلوك الحالي الذي يحتوي كل وحدة نمطية على ارتباط مُصدَّر لنفسها ، وهذا هو سبب أسباب using A سيكون هناك ارتباط ناعم بـ A متاح.

سأصاب بخيبة أمل كبيرة إذا كان لا يزال لدينا عدة كلمات رئيسية بعد كل هذا.

يعجبني التماثل بين import و export . (كما أشار أحدهم في مكان ما.)

لا يبدو إجراء "عمليات ربط صلبة" دائمًا على أنه الإعداد الافتراضي الأكثر أمانًا من حيث امتداد الطريقة. كان هناك اقتراح مرتبط ولكن منفصل إلى حد ما للمطالبة بتأهيل الوحدة النمطية لتمديد الأسلوب الذي يمكن أن يزيل الحاجة إلى "الارتباطات الصلبة".

هناك حاجة أيضًا إلى روابط صلبة لهذا الغرض:

import Package: x
x = 1   # gives an error

والأهم من ذلك ، أن هذا الاقتراح لن يؤدي دائمًا إلى عمليات ربط صعبة - فقط للأشياء التي تدرجها بشكل صريح. إن طلب قول import بدلاً من using لا يضيف الكثير من الأمان.

تأتي السلامة من غالبية الأماكن التي لا تقوم بتمديد الطريقة التي يمكن أن تفلت بشكل جيد من خلال الربط الناعم. أعتقد أنه لا يزال يجب أن يكون لدينا طريقة لطلب ارتباط ناعم معين دون الاضطرار إلى استيراد جميع صادرات الحزمة (أو الحصول على ربط ناعم معين لم يتم تصديره).

هل لا يزال لدينا تحذير بشأن الكتابة فوق الربط المستورد؟

أعتقد أن طلب مؤهل وحدة فكرة جيدة. الآن لمعرفة ما إذا كان يتم تقديم وظيفة أو تمديد طريقة ، يجب عليك إلقاء نظرة على محتويات الحزمة بالكامل للحصول على بيان import A: func .

هل لا يزال لدينا تحذير بشأن الكتابة فوق الربط المستورد؟

أعتقد أنه في الواقع خطأ الآن.

هناك اقتراح آخر يحافظ على كلتا الكلمتين الرئيسيتين ، لكنه يبسط الأمور قليلاً:

  1. أضف الصيغة import A: ...
  2. استنفد using A:
  3. في using A.B ، اطلب A.B ليكون وحدة ، ووثق أنه اختصار لـ import A.B; import A.B: ... .

بهذه الطريقة ، يمكن إنجاز كل شيء باستخدام import فقط ، لكن using X متاح للراحة. سيكون هذا أيضًا من السهل الانتقال إليه بشكل خاص.

راجع للشغل ، يبدو using غير متناسق كما نشرت هنا . إذا احتفظنا بـ using ، فيجب إعادة تسميته إلى use إن أمكن.
أعتقد أننا يجب أن نطلب القياس الكمي للوحدة عند توسيع الوظائف لأن معناها أوضح بكثير من نمط الاستيراد ثم التمديد.

نهجي المفضل:

  • تتطلب بادئة وحدة صريحة للتمديد
  • إذا كنت تريد اسم الوحدة فقط وليس رموزها ، فاستخدم using A: A
  • قم بإزالة import ونوع الربط الذي يتم إنشاؤه

الأشياء التي يجب أن تحدث لتنفيذ https://github.com/JuliaLang/julia/issues/8000#issuecomment -327512355:

  • تغيير سلوك using A للإستيراد الصعب A
  • إزالة دعم using A: x
  • إزالة الدعم لـ using A.x حيث لا يكون x وحدة فرعية
  • إزالة الدعم لـ import A.x حيث لا يكون x وحدة فرعية
  • إضافة دعم لبناء جملة ... إلى import

يستخدم using A: x كثيرًا وهو مفيد جدًا. أنت تقول أنك تريد x في مساحة الاسم الخاصة بك ولكنك لا تريد تمديدها. في import A: x ، أنت تقول أنك تريد أن تكون قادرًا على تمديد x . هناك تمييز ذو مغزى بين وجود وظيفة متاحة للاستخدام والقدرة على توسيعها.

عند التفكير في الأمر ، أقول إن أكبر مشكلة واحدة هنا هي أن using A.B يقوم بأمرين: إذا كان B وحدة نمطية ، فإنه يستورد جميع صادراته ، وبخلاف ذلك فقط الواردات اللينة B . أعتقد أننا يجب أن نصلح ذلك فقط ، ونجعل using A.B مسموحًا به فقط للوحدات النمطية ، ولدينا using A: a, b لاستيراد ارتباطات معينة بسيطة واحدة تلو الأخرى.

أفضل ما إذا كانت هناك طريقة واحدة لكتابة import A: x بدلاً من أن تكون معادلة لـ import A.x .

أنا أصوت لـ import A: x حيث يمكننا أيضًا القيام بذلك ؛ قد يبدو import A: x, y, @z لكن import A.x, A.y, a.@z قبيحًا.

هل حذف هذا من 1.0 يعني أنه سيتم ترك كل من using و import مقابل 1.0؟ هذا مؤسف بعض الشيء في رأيي.

ماذا عن:

  • بادئة وحدة القوة للتمديد. هذا سيجعل الكود أكثر وضوحًا من أن الامتداد مقصود بدلاً من أن يكون عرضيًا من استيراد في ملف آخر.
  • يصبح $ using A import A: ...
  • using A.X ( X عبارة عن وحدة نمطية) يصبح استيراد A.X: ...
  • using A: X ( X ليس وحدة نمطية) يصبح import A: X
  • import A: X لم يتغير لكن لا يمكنك تمديد X تلقائيًا (انظر النقطة الأولى)
  • حذف الكلمة الأساسية using

هل أفتقد بعض حالة الاستخدام؟ ربما تم اقتراح هذا بالفعل ...

ما يعجبني في أن أكون صريحًا بشأن الوحدة عند التمديد هو أن الامتداد يصبح أكثر محلية. في الوقت الحالي ، عند تمديد إحدى الطرق ، من الشائع وضع الاستيراد بالقرب من الجزء العلوي من الوحدة النمطية (والذي قد يكون في ملف مختلف تمامًا!). عندما يتم حذف الطريقة الممتدة عادة ما يتم نسيان بيان الاستيراد.

أعتقد أن هذا هو نفس اقتراحي أعلاه ، والذي حصل على قدر لا بأس به من الدعم. يريد JeffBezanson حقًا الاحتفاظ بـ using A على الأقل لسهولة الاستخدام و using A: x لأنه على ما يبدو (لم يتم بيع هذا الأمر) ، إنها حالة استخدام مهمة لتكون قادرًا على استيراد ارتباط في بطريقة لا يمكنك تمديدها. هناك بعض المقترحات للسير في الاتجاه الآخر واستبدال import بـ using لكن لم يحصل أي منهم على الكثير من الجاذبية (يبدو import أكثر أهمية).

أعتقد أن الاختلاف في:

  • استيراد A: x ، y # ارتباطات صلبة لـ x و y من A

بافتراض أن معنى "الربط الثابت" هو أنه يمكنك تمديده بدون بادئة الوحدة النمطية ، في إصداري لا توجد روابط صلبة. إذا كنت ترغب في التمديد ، فأنت تقوم ببدء الوحدة النمطية حيث تقوم بتمديدها بالضبط. لا توجد عبارات مخيفة import في ملفات أخرى تغير المعنى سواء كان الشيء امتدادًا أم لا.

و using A: x لأنه على ما يبدو (لم يتم بيعي لهذا الأمر) ، من المهم أن تكون قادرًا على استيراد ارتباط بطريقة لا يمكنك تمديدها.

ألا يتم فرض بادئة الوحدة النمطية للتعامل مع ذلك؟ أم أننا نتحدث عن غير وحدات مثل:

module M
    x = 1
end

يعطي كلا من import M: x; x = 2 و using M: x; x = 2 نفس رسالة التحذير لذلك لا أرى سبب المشكلة ...

يبدو أن الاحتفاظ بـ using A لسهولة أكثر من import A: ... مبالغ فيه بعض الشيء في رأيي.

ألا يتم فرض بادئة الوحدة النمطية للتعامل مع ذلك؟

نعم؛ إذا كان عليك تأهيل الوظائف لتمديدها ، فلن تكون هذه النقطة ذات صلة.

الاستمرار في استخدام "أ" لسهولة الاستيراد "ج": ... يبدو مبالغًا فيه بعض الشيء في رأيي.

أرى الأمر في الاتجاه المعاكس. جعل الناس يتحولون من using A (وهو أمر لطيف وقصير وكلنا معتادون على ذلك) إلى import A: ... فقط لتلبية مطلب اصطناعي يفيد بأن هناك كلمة رئيسية واحدة مفرطة.

من قراءة الموضوع ، يبدو أن القيمة الرئيسية في وجود كلمتين رئيسيتين هي التمييز بين الارتباطات التي يمكن تمديدها أم لا (الربط الثابت). مع وضع ذلك في الاعتبار ، أعتقد أن هناك حلين قابلين للتطبيق:

  • كلمة رئيسية واحدة + تتطلب بادئة للتوسيع
  • كلمتان رئيسيتان ، واحدة للاستخدام العادي (غير الموسع) ، والثانية لتوسيع الاستخدام ، أقترح using و extending في هذه الحالة. import جيد ، لكن extending يجعل سبب وجود الكلمة الرئيسية الثانية واضحًا

في كلتا الحالتين ، أقترح أن يكون using كما هو الآن مع إضافة أحد العناصر التالية لربط الوحدة فقط Foo :

  • using Foo: nothing (يعمل الآن)
  • using Foo: Foo (يعمل الآن)
  • using Foo: (يمكن إضافته لاحقًا)

ثم يجب أن يتصرف extending مماثلاً لـ using مع الاختلاف الوحيد هو أنه يمكنك تمديد الارتباطات التي يتم إحضارها بـ extending ، وربما عدم السماح extending Foo بحيث يكون أن تكون صريحًا.

السلوك الحالي

| | إتاحته (باستخدام) | جعل قابلة للتمديد (استيراد) |
| ------------------- | -------------------------- | ---------------------- |
| الوحدة فقط | using module: module أو using module: nothing | import module |
| كل شيء يتم تصديره | using module (أثر جانبي: يتصرف مثل import module أيضًا) | ؟ |
| أشياء معينة | using module: x,y | import module: x,y |

اقتراح

| | إتاحته (باستخدام) | جعل قابلة للتمديد (استيراد) |
| ----------------- | ------------------------ | -------------------------- |
| الوحدة فقط | using module | import module |
| كل شيء يتم تصديره | using module: * | import module: * |
| أشياء معينة | using module: x,y | import module: x,y |

الشيء الجميل في هذا هو أن استيراد المزيد يتوافق مع كتابة المزيد. أي أن تبدأ بـ using module وإذا كنت تريد استيراد متغير مباشرة إلى مساحة الاسم ، فأنت تضيف : x بدلاً من إزالة nothing أو module . وهذا يعني أيضًا أن أقصر شيء تكتبه يتضمن الأقل.

يمكنك أيضًا عمل using: *,x لإتاحة كل ما يتم تصديره و x الذي لم يتم تصديره.

حل وسط للتوافق مع الإصدارات السابقة:

| | إتاحته (باستخدام) | جعل قابلة للتمديد (استيراد) |
| ----------------- | ------------------------ | -------------------------- |
| الوحدة فقط | using module: | import module: |
| كل شيء يتم تصديره | using module: * | import module: * |
| أشياء معينة | using module: x,y | import module: x,y |

احتفظ بحوالي using module و import module مع السلوك الحالي للتوافق مع الإصدارات السابقة ولكن قم بإهماله.

FelixBenning : import Module حاليًا لا (من تلقاء نفسه) يجعل أي شيء قابل للتمديد أكثر من using Module ، إنه يقوم فقط بتحميل الكود وإحضار Module (ولا شيء آخر) إلى مساحة الاسم .

فقط لتعكس ما قلته في Slack وحتى لا يتلاشى في فتحة Slack:

لا أعتقد أن جعل using X: * هو الخيار الافتراضي لجعل كل شيء مُصدَّر متاحًا مقابل using X فقط سيجعل الناس بالضرورة أكثر حذرًا مما يستوردونه. أعلم ، أن الإشارة إلى كيفية قيام الآخرين بذلك يعتبر شكلًا سيئًا ، لكن Python تحتوي بشكل أساسي على تلك الدلالات مع import X و import X: * ، ومع ذلك فإن نظامهم الإيكولوجي مليء بواردات النجوم 🤷‍♂️ (و من المعروف أنهم يكرهون ذلك) لا أعتقد أن النص الأطول بشكل هامشي الذي يجب على المرء كتابته يمنع الناس من فعل ما يعتبرونه الأكثر ملاءمة: فقط قم باستيراد / استخدام كل شيء ودع المترجم يكتشف ذلك. لهذا السبب أشعر بالقلق من الرصاصة السحرية لجعل الناس يكتبون هذا النجم بشكل صريح.

علاوة على ذلك ، import module: * و using module: * غير متاح للمعنى المقترح. لها معنى بالفعل حيث أن * هو معرف Julia صالح ويمكن استيراده / استخدامه تمامًا مثل + أو الكلمة mul .

tpapp إما أنني قد أسأت فهم الوثائق مرة أخرى ، أو أن import Module يجعل Module.x قابل للتمديد. بينما using Module: x لا يجعل Module.x قابل للتمديد. لذلك فإن import Module يجعل شيئًا ما متاحًا للتمديد و using Module يفعل ذلك أيضًا ، ولهذا السبب لاحظت أن الاستخدام له هذا التأثير الجانبي.
grafik
(من https://docs.julialang.org/en/v1/manual/modules/)

لا يهم حقًا أي واحد منا على حق - في كلتا الحالتين يكون الوضع الحالي فوضويًا بشكل واضح إذا لم نتمكن حتى من معرفة ما يفعله كل شيء.

mbauman نقطة جيدة - لقد نسيت ذلك. لا أهتم حقًا بـ * فقط بنية امتلاك using تعكس الأشياء import مع اختلاف الاستيراد مقابل استخدام ما إذا كانت الأشياء تصبح قابلة للتمديد أم لا. لذلك إذا كان هناك رمز أكثر ملاءمة - all ، __all__ ، everything ، exported ، ...؟ أنا مستعد تماما لها. أعتقد فقط أنه من المحتمل أن ينعكس استيراد المزيد من خلال كتابة المزيد.

ولكن إذا كنت لا تريد ذلك على الإطلاق ، فيمكنك بالطبع أيضًا اختياره

| | إتاحته (باستخدام) | جعل قابلة للتمديد (استيراد) |
| ----------------- | ------------------------ | -------------------------- |
| الوحدة فقط | using module: module | import module: module |
| كل شيء يتم تصديره | using module | import module |
| أشياء معينة | using module: x,y | import module: x,y |

أو

| | إتاحته (باستخدام) | جعل قابلة للتمديد (استيراد) |
| ----------------- | ------------------------ | -------------------------- |
| الوحدة فقط | using module | import module |
| كل شيء يتم تصديره | using module: module | import module: module |
| أشياء معينة | using module: x,y | import module: x,y |

ولكن مهما كانت النتيجة النهائية ، يجب أن تكون متسقة. وفي الوقت الحالي ، الأمر ليس كذلك.

using A يجعل A.f قابل للتمديد ، _not_ f بمفرده. من أجل تمديد _just_ f بدون التصريح عن الوحدة التي تريد توسيعها ، يجب أن تصل إلى import A: f صراحة. وإلا فلا يزال يتعين عليك تأهيله.

تحقق مما يلي لمعرفة دلالات using

julia> module A
        export f
        f() = "no args in A"
       end
Main.A

julia> f()
ERROR: UndefVarError: f not defined
Stacktrace:
 [1] top-level scope at REPL[2]:1

julia> using .A

julia> f()
"no args in A"

julia> f(1)
ERROR: MethodError: no method matching f(::Int64)
Closest candidates are:
  f() at REPL[1]:3
Stacktrace:
 [1] top-level scope at REPL[5]:1

julia> f(x) = "one arg where?"
ERROR: error in method definition: function A.f must be explicitly imported to be extended
Stacktrace:
 [1] top-level scope at none:0
 [2] top-level scope at REPL[6]:1

julia> A.f(x) = "one arg where?"

julia> f(1)
"one arg where?"

وهذا بالنسبة لدلالات import :

julia> module A
        export f
        f() = "no args in A"
       end
Main.A

julia> f()
ERROR: UndefVarError: f not defined
Stacktrace:
 [1] top-level scope at REPL[2]:1

julia> import .A

julia> f()
ERROR: UndefVarError: f not defined
Stacktrace:
 [1] top-level scope at REPL[4]:1

julia> A.f()
"no args in A"

julia> f(1)
ERROR: UndefVarError: f not defined
Stacktrace:
 [1] top-level scope at REPL[6]:1

julia> A.f(1)
ERROR: MethodError: no method matching f(::Int64)
Closest candidates are:
  f() at REPL[1]:3
Stacktrace:
 [1] top-level scope at REPL[7]:1

julia> f(x) = "one arg where?"
f (generic function with 1 method)

julia> f(1)
"one arg where?"

julia> A.f(1)
ERROR: MethodError: no method matching f(::Int64)
Closest candidates are:
  f() at REPL[1]:3
Stacktrace:
 [1] top-level scope at REPL[10]:1

julia> A.f(x) = "one arg where in A"

julia> A.f(1)
"one arg where in A"

FelixBenning : نعم ، أعتقد أنك أسأت فهمك. FWIW ، أعتقد أن "... يجعل Foo.x قابل للتمديد" هي طريقة مربكة للتعامل مع التمييز --- يمكنك دائمًا تحديد طرق لأسماء الوظائف المؤهلة بالكامل. ما يحدث مع using Foo: x هو أنه لن يتم إحضار Foo نفسه إلى مساحة الاسم.

بالمناسبة ، عند إعادة قراءة هذا الموضوع ، أتساءل عما إذا كان # 25306 قد أوصلنا إلى نوع من المستوى المحلي الأمثل ، والقرار الوحيد المتبقي هو ما إذا كنا بحاجة إلى عمليات استيراد غير قابلة للتوسيع في مساحة الاسم (حاليًا using Foo: f ). ولكن نظرًا لكسر هذا الأمر ، فقد يستفيد الفصل اليدوي من إعادة الكتابة في هذه الأثناء ، يجد العديد من المستخدمين الأمر برمته محيرًا.

هذه هي الطريقة التي سأتعامل بها مع الوضع الراهن في المستندات:

  1. يقوم using M بتحميل الوحدة ، وإحضار M ورموزها المصدرة إلى مساحة الاسم. هذه هي الحالة الوحيدة التي تكون فيها الصادرات مهمة.
  2. بمجرد حصولك على M ، يمكنك استخدام الأسماء المؤهلة مثل M.y لـ (أ) الوصول إلى الرموز غير المصدرة و (ب) إضافة طرق إلى الوظائف ، بغض النظر عما إذا كانت مُصدرة أم لا
  3. تمنعك Julia من إضافة طرق إلى الوظائف ما لم تستخدم أسماء مؤهلة مثل M.f ، أو ...
  4. ... import M: f ، إذًا يمكنك فقط استخدام f عند تحديد الطرق.
  5. import M و using M: x لجلب M أو x ( وليس M ) ، على التوالي ، في مساحة الاسم ، على التوالي. يحب بعض الأشخاص استخدام هذه النماذج في كود الحزمة للتأكد من أن مساحات الأسماء الخاصة بهم تظل نظيفة (اربط أدلة الأنماط ذات الصلة هنا).

يعكس الطلب بشكل أو بآخر حالات استخدام مصادفة مع استخدام أكثر تقدمًا. كل ما سبق ينطبق على الوحدات الفرعية ، مع M.A بدلاً من M .

ماذا عن هذا:

  • using M ينقل M إلى النطاق
  • using M: x يجلب M.x إلى النطاق (مثل x )
  • يجلب using M: ... جميع الرموز المصدرة لـ M إلى النطاق
  • يجلب using M: x, ... جميع الرموز المُصدَّرة M إلى النطاق وأيضًا x (والتي قد تكون غير مُصدَّرة)
  • لا يوجد import . تحتاج إلى استخدام الاسم المؤهل لتوسيع وظيفة. (أو using M; const foo = M.foo مثلما يمكن أن يفعله المرء الآن.)
  • في كل ما سبق ، يمكن أيضًا أن يكون M وحدة فرعية ، على سبيل المثال Foo.Bar و x يمكن أيضًا أن يكون x as y بالمعنى الحالي.

أو نستخدم import بدلاً من using مما يجعل هذا يساوي https://github.com/JuliaLang/julia/issues/8000#issuecomment -355960915.

استخدام شائع جدًا (خاصة في "البرامج النصية" ، ولكن أيضًا في حزم لأنماط معينة)

using Foo, Bar, Baz

والاعتماد فقط على الرموز المصدرة. سيكون هناك بعض الفوائد من إبقاء هذا الأمر أبسط ، ربما بهذه البساطة كما هو الآن.

tpapp

أظن أنك فهمت بشكل خاطئ. FWIW ، أعتقد أن "... يجعل Foo.x قابل للتمديد" هي طريقة مربكة للتعامل مع التمييز - يمكنك دائمًا تحديد الأساليب لأسماء الوظائف المؤهلة بالكامل.

حسنًا ، هل يمكنني تمديد Foo.x بعد using Foo: x ؟ لأنه إذا كانت الإجابة بنعم ، فلن تكون المستندات كاملة (انظر لقطة الشاشة الخاصة بي). إذا لم يكن الأمر كذلك ، فقد فهمت تمامًا كيفية عمل هذه العبارات ومن الواضح تمامًا أن import Foo فعل شيئًا لجعل Foo.x قابل للتوسيع. لذلك فهو يجعل حرفيا Foo.x متاحًا للتمديد. بكل معاني هذه الكلمات. من المؤكد أنها لا تجعل x متاحًا للتمديد ، ولكن هذا هو ما يعنيه import Foo: x

حسنًا ، هل يمكنني تمديد Foo.x بعد using Foo: x ؟

ليس إلا إذا قمت بإحضار Foo إلى مساحة الاسم بطريقة ما (على سبيل المثال ، using Foo ).

لقد فهمت تمامًا كيف تعمل هذه العبارات

لست متأكدًا تمامًا من هذا - ومع ذلك ، إذا كانت لديك أسئلة حول الوحدات ومساحات الأسماء ، فيرجى التفضل باستخدام منتدى الخطاب.

من الواضح تمامًا أن import Foo فعل شيئًا لجعل Foo.x قابل للتوسيع

فقط بمعنى أنه يجب أن تكون قادرًا على الإشارة إلى وظيفة بطريقة ما باستخدام اسم مؤهل قبل إضافة طرق إليها.

ثم الوثائق ليست كاملة

أعتقد أنه ، بطريقة غريبة. في هذا المثال بالذات ، إذا كان كل ما تفعله هو using MyModule: x, p ؛ ثم لا توجد طرق متاحة للتمديد ، وبالتالي فإن الجدول صحيح.

أوافق على أنه يمكن كتابته بشكل أفضل ، كما قلت أعلاه. كثير من الناس غير المعتادين على مساحات الأسماء يجدونها مربكة. و TBH ، السيرك كله using / import هو أمر محير إلى حد ما ، ومن هنا جاءت هذه المشكلة.

tpapp

حسنًا ، هذا هو الشيء: ليس من الواضح تمامًا أنه يمكنك تمديد كل وظيفة بالاسم الكامل إذا كانت الوحدة في مساحة الاسم. أعلم أن هذا هو السلوك الحالي ، لكنني لا أعتقد أن أي شخص لا يعرف ذلك سيفترض ذلك بالفعل. خاصة وأن التواجد في مساحة الاسم لا يعني دائمًا أنه قابل للتمديد أيضًا. إذا فعلت ذلك using module:x فلا يمكنني تمديد x . بينما يمكنني تمديد x ، إذا استخدمت import module:x . لذلك فمن المعقول أن يكون الفارق بين using و import هو ما إذا كان بإمكانك تمديد الوظائف المستوردة أم لا.

باستخدام هذا الافتراض سيكون من المنطقي ، إذا كان using module سيسمح فقط باستخدام module.x لكن لن يسمح بتمديد module.x . بينما import module سيسمح بتمديد module.x . لذلك إذا أخذت هذا الافتراض وقرأت التوثيق ، ستجد أن شيئين خاطئين بشأن ذلك.

  1. يسمح لك using module بتمديد module.x . لذلك من المتعلمين من منظور المتعلمين using module له تأثير جانبي ، أنه يعمل أيضًا مثل import module - أي أنه يجعل module.x قابل للتمديد. وجعل الأشياء قابلة للتمديد هو شيء import ، وليس شيء using
  2. على عكس import ، فإن using لا يجعل فقط module متاحًا ، بل كل شيء فيه.

لذلك هذا ما حاولت تمثيله على طاولتي. إذا تم استخدام كلمتين مختلفتين (استيراد / استخدام) ، فيجب عليهم فعل شيئين مختلفين ويجب أن يكون ذلك واضحًا تمامًا. إذا كان using يسمح أحيانًا بالتمديد وفي أحيان أخرى لا يكون هذا سلوكًا غير متوقع.

البديل الجيد هو إزالة الاستيراد تمامًا كما يقترح martinholters . لا يمكنك ببساطة استخدام كلمتين بشكل عشوائي لأشياء معينة. إذا كان import يعني جعل الأشياء قابلة للتمديد عند استيراد وظائف معينة ، بينما using module: foo لا يسمح بذلك ، فيجب أن يحدث نفس السلوك عندما تقوم فقط بتضمين module في مساحة الاسم.

فقط لأنك تستطيع تمديد كل شيء باسمه الكامل في الوقت الحالي إذا كانت الوحدة في مساحة الاسم ، فهذا لا يعني أن هذا أمر واضح أو مباشر.

إما أن يكون التواجد في مساحة الاسم كافيًا ، فيجب أن أكون قادرًا أيضًا على تمديد x إذا قمت بتضمينه في مساحة الاسم مع using module:x أو أن التواجد في مساحة الاسم ليس كافيًا ، وبعد ذلك يجب علي أيضًا لن تكون قادرًا على تمديد module.x عند استخدام الأمر using .
أو الخيار الثالث: لا يوجد import وعليك ببساطة تمديد الوظائف باسمها الكامل طوال الوقت.

ليس من الواضح على الإطلاق أنه يمكنك تمديد كل وظيفة بالاسم الكامل إذا كانت الوحدة في مساحة الاسم.

أوافق ، ولهذا أجادل من أجل إعادة كتابة المستندات. ومع ذلك ، هذا عرضي للقضية الحالية. سيكون من الأفضل الاحتفاظ (1) بمقترحات لتحسين التوثيق حول API الحالي و (2) مقترحات لإعادة تصميمها بشكل منفصل ، حتى لو كان الاثنان مرتبطين إلى حد ما. أخطط لعمل علاقات عامة لـ (1) قريبًا.

tpapp لا يمكنك توثيق أي شيء لا معنى له بطبيعته. أي من هذه الوثائق غير صحيحة:

  1. "يمكنك تمديد أي شيء موجود في مساحة الاسم" (لأن using module:x لا يسمح لك بتمديد x )
  2. "التواجد في مساحة الاسم ليس كافيًا للتمديد ، ولهذا السبب توجد كلمات منفصلة using و import " (خطأ لأنه بالنسبة للأسماء الكاملة ، يكفي في الواقع أن تكون في مساحة الاسم - إيقاف ذلك كان اقتراحي كافيا)
  3. "يمكنك تمديد أي شيء في Namespace باسمه الكامل" (الأمر الذي يتطلب import module:x للتوقف عن الوجود ليكون الحقيقة الكاملة - اقتراح martinholters )

أي من هؤلاء سيكون مقبولا. لكن لا شيء من هذه حقيقة واقعة. في الواقع حاليًا ، هناك كلمتان مختلفتان تستخدمان "لاستيراد الأشياء" ولكنهما لا تمتلكان في الواقع حالة استخدام مميزة. إنه مثل حلقة for تتصرف أحيانًا مثل حلقة while إذا قمت بالتكرار على القيم المنطقية. لن يجعل أي قدر من الوثائق ذلك غير مربك

لا يمكنك توثيق شيء لا معنى له بطبيعته.

واجهة برمجة التطبيقات للوحدات النمطية الحالية محددة جيدًا ، لذا يمكن توثيقها (إنها كذلك بالفعل ، أعتقد أنها يجب أن تكون أفضل).

أي من هذه الوثائق غير صحيحة:

يرجى أن تكون لطيفًا حتى تنتظر العلاقات العامة الخاصة بي (أو الخاصة بشخص آخر) والتعليق على النص الفعلي الذي سيكون هناك. إن افتراض التوثيق الافتراضي ثم الادعاء بأنه غير صحيح هو مجرد إضافة ضوضاء إلى هذه المناقشة.

tpapp ربما كان يجب أن أقول ،

لا يمكنك توثيق أي شيء بطريقة غير مربكة لا معنى لها بطبيعتها

أعني إلى حد ما الرمز هو كل الوثائق التي تحتاجها بشكل صحيح؟ ما الخطأ فى ذلك؟ الوقت المستغرق لهضمه. ولا أرى حاليًا طريقة مختصرة لوصف كيفية عملها ، لأنها مليئة بالاستثناءات. الاستثناءات التي لا ينبغي أن تكون موجودة في المقام الأول.

هل حقًا لا ترى ما أحاول أن أنقله؟

أعتقد أن هناك اتفاق عام على أن الوضع الحالي معقد بلا داع وغير موثق بشكل كاف. ومما لا شك فيه أن تبسيط الآليات سيجعل عملية التوثيق أسهل. لكن مثل هذا التبسيط سينهار ، لذلك لا يمكن القيام به قبل الإصدار 2.0. إذن ، هل وجهة نظرك هي أن تحسين التوثيق قبل ذلك لن يكون منطقيًا؟ ثم أختلف. أرى مسألتين منفصلتين: التبسيط الذي يتم إجراؤه مع الإصدار 2.0 (الذي تدور حوله هذه المشكلة) والذي سيشمل (نأمل) تحديثات الوثائق الضرورية وتحسين توثيق الأعمال الحالية التي يبدو أنها من خلال قراءة هذا الموضوع تبدو مطلوبة بشدة ولكنها مشكلة أخرى .

بعد إجراء # 38271 ، أعتقد أن الأسئلة المعلقة

كيفية التعامل مع طرق الإضافة للوظائف في الوحدات الأخرى

  1. تتطلب دائمًا أسماء مؤهلة بالكامل ( Foo.bar() = ... ) ،
  2. السماح أيضًا فقط عندما يكون الرمز في النطاق ( using Foo: bar; bar() = ... )
  3. (2) ، ولكن أدخل في النطاق بطريقة خاصة ( الوضع الراهن ، import Foo: bar; bar() = ... )

الصيغة التي تتعامل مع قوائم التصدير واسم الوحدة فقط

  1. يجلب using Foo جميع الرموز المصدرة في Foo إلى النطاق ، import Foo فقط الوحدة ( الوضع الراهن )
  2. using Foo: ... أو بناء جملة آخر مشابه ، ثم using Foo فقط الوحدة.

سيسمح (1 | 2) & 2 بالتوحيد في كلمة رئيسية واحدة ، إما using أو import ، بتكلفة فقدان سطر واحد

using LinearAlgebra, Random, StaticArrays

لست متأكدًا من أن الأمر يستحق ذلك ، حتى بدون التفكير في التغيير المفاجئ.

هذه ليست واحدة من تلك المشكلات التي تقدم حلاً نظيفًا فاته التصميم الأصلي للتو ؛ هناك مقايضات. سأنتظر وأرى ما إذا كان بإمكان التوثيق الأفضل تحسين تجربة المستخدم مع الحفاظ على الإعداد الحالي (1.0).

بالنسبة إلى الإصدار 2.0 ، أعتقد أن مجرد تنظيف بناء الجملة ليكون أكثر اتساقًا ووصفًا لما يحدث بالفعل سيكون أمرًا رائعًا. شيء مثل:

| قبل | بعد |
| - | - |
| using Foo | useall from Foo |
| import Foo | use Foo |
| using Foo: a | use a from Foo |
| import Foo: a و import Foo.a | extend a from Foo |

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات