לואה (שפת תכנות)

מתוך ויקיפדיה, האנציקלופדיה החופשית
קפיצה לניווט קפיצה לחיפוש
לואה
Lua
סמליל שפת התכנות לואה
סמליל שפת התכנות לואה
פרדיגמות תכנות מונחה דגמי אב, תכנות אימפרטיבי, תכנות פרוצדורלי, תכנות פונקציונלי
שנה 1993
מתכנן Roberto Ierusalimschy, Waldemar Celes, Luiz Henrique de Figueiredo
מפתח הקבוצה לגרפיקה ממוחשבת באוניברסיטה הקתולית (PUC Rio) שבריו דה ז'ניירו בברזיל.
גרסה אחרונה 5.3.5
טיפוסיות דינמית
מימושים Lua, LuaJIT
ניבים Metalua, Idle, GSL Shell
הושפעה על ידי C++, CLU, Modula-2, Scheme, SNOBOL
השפיעה על GameMonkey, Io, JavaScript, Julia, MiniD, Red, Ring, Ruby, Squirrel, MoonScript
רישיון רישיון MIT
סיומת .lua
https://www.lua.org

Lua (לואה, מפורטוגזית: ירח) היא שפת תכנות דינמית. היא מצטיינת בכך שלמרות היותה שפה דינמית, היא לא דורשת משאבים רבים. היא משמשת בעיקר כשפת תכנות משובצת בתוכניות אחרות. אוצר המילים של השפה ניתן להרחבה בקלות. המפרש הסטנדרטי של השפה כתוב בשפת C, ולכן השפה זמינה בקשת רחבה של פלטפורמות.

את Lua מפתחת הקבוצה לגרפיקה ממוחשבת באוניברסיטה הקתולית (PUC Rio) שבריו דה ז'ניירו בברזיל. השפה התפרסמה ב-1993 בכנס הברזילאי השביעי להנדסת תוכנה. הגרסה הציבורית הראשונה הייתה ב-8 ביולי 1994. נכון להיום הגרסה האחרונה היא 5.3.5. בכל שינוי גרסה יש תוספות והרחבות לשפה.

המוטיבציה לפיתוח השפה נבעה מכך שבברזיל משנת 1977 ועד 1992 הייתה הגבלה על הסחר במחשבים, בתוכנה ובחומרה.

המימוש הרגיל של השפה הוא כתוכנה חופשית המופצת ברישיון MIT. בניגוד להרבה מימושים דומים, יש לה איסוף זבל על ידי סימון ומחיקה ולא רק על ידי מניית התייחסות.

היסטוריה[עריכת קוד מקור | עריכה]

Lua החלה את דרכה בשנת 1993 בפרויקטים שנכתבו באוניברסיטה הקתולית בריו עבור חברת הנפט הברזילאית פטרוברז. היו צריכים לתאר בקלות נתונים מסוגים מגוונים. התברר להם שהדרך היעילה ביותר לייצג אותם היא על ידי שפת תכנות ייעודית. לפני שכתבו את Lua כתבו גם שפה מוגבלת יותר בשם Sol (ראשי תיבות באנגלית של Simple Object Language, אך גם המילה ”שמש“ בפורטוגזית).

קהילה[עריכת קוד מקור | עריכה]

למרות יעודה כשפה משובצת (התלויה בעיקר בשפת C), Lua הצליחה לצבור פופולריות ותאוצה בשנים האחרונות בין מפתחי קוד פתוח ולה קהילה עצמאית שמפתחת לה כלים וספריות המאפשרים בה פיתוח נוח ורב תחומי ללא תלות ב־C או בשפות אחרות.

LuaRocks[עריכת קוד מקור | עריכה]

מערכת ניהול החבילות של Lua (הופיעה לראשונה ב־2007, הכתובה גם היא בשפה עצמה[1]) נקראת LuaRocks והיא מאפשרת שיתוף ספריות וקוד הכתובים ב־Lua. החבילות עצמן מכונות ”rocks“ בצירוף פירוש שם השפה Lua בפורטוגזית ”ירח“, נגזר המונח ”אבני ירח“ לתאר פיסות קוד הכתובות בשפה שהם בדרך כלל רכיבי Lua או אסופות של רכיבים המספקים פונקציונליות ממוקדת מטרה.

המערכת יודעת לטפל ביחסי תלות בין החבילות עצמן, בגרסאות שלהן, ושל מפרש ה־Lua הזמין במחשב ויוצרת סביבה נוחה לפיתוח יציב ושיתופי ב־Lua. החבילות מסודרות במקום מרוכז בכל מחשב וכך חוסכות הכלה מיותרת של אותם רכיבים בכל פרויקט Lua חדש.

מבין המיזמים המוכרים ביותר בקהילה נמנים Kepler Project שהפך את Lua כשפה ייעודית עבור יישומוני רשת, ואת כלי התיעוד והביאור LuaDoc ו־LDoc, שהם כלי התיעוד והביאור העיקריים כיום עבור קוד שכתוב ב־Lua.

נכון ל־2019, הנתונים הסטטיסטים של LuaRocks מראים כ־20 אלף חברים רשומים (אין צורך להיות רשום כדי להוריד חבילות), כ־2500 חבילות זמינות,[2] ובין 40 ל־60 אלף[3] הורדות יומיות.

תחביר[עריכת קוד מקור | עריכה]

מבני הנתונים הבסיסיים ב־Lua הם:

  • משתנים פשוטים, שיכולים להיות מספרים או מחרוזות.
  • מערך אסוציאטיבי (מילון) שיכול לתפקד גם כרשימה, בעת הצורך.
  • מבני נתונים מורכבים יותר מתוארים כקינון מערכים בתוך מערכים במידת הצורך.
-- Plain list of items, can be accessed or iterated as `colors[i]`.
local colors = {"Red", "Green", "Blue"}

-- A dictionary of key-value pairs, where `shapes[6]` retrieves the value "Hexagon".
local shapes = {
  [1] = "Monogon", -- non-Euclidean
  [2] = "Digon", -- non-Euclidean
  [3] = "Trigon", -- Triangle
  [4] = "Tetragon", -- Rectangle
  [5] = "Pentagon",
  [6] = "Hexagon",
  [7] = "Heptagon",
  [8] = "Octagon",
  [9] = "Nonagon",
  [10] = "Decagon"
}

-- A dictionary of key-value pairs, where `days["Monday"]` retrieves the value 2.
local days = {
  ["Sunday"] = 1,
  ["Monday"] = 2,
  ["Tuesday"] = 3,
  ["Wednesday"] = 4,
  ["Thursday"] = 5,
  ["Friday"] = 6,
  ["Saturday"] = 7
}

-- Plain table with numbers:
local numbers = {1, 2, 3, 4, 5, 6}

-- Lua tables are indexed from 1 by default.
-- However you can define a Lua table with negative indexes:
local my_table = {
  [-1] = "My 1st item",
  [0] = "My 2nd item",
  [1] = "My 3rd item"
}

-- Tables can be nested indefinitely to describe complex data structures.
local person_record = {
 names = {
 first = "John",
 -- Note that `nil` values will break `for ipairs() do` iterations.
 middle = nil,
 last = "Smith",
 -- Lua tables can also include functions.
 full_name = function(this)
 local name = ""
 if this.first then name = this.first..' ' end
 if this.middle then name = name..this.middle..' ' end
 if this.last then name = name..this.last end
 return name
 end
 -- Call this function with the colon `:` operator as such:
 -- `person_record.names:full_name()`
 },
 residence = {
 country = "US",
 state = "NY",
 city = "New York City"
 }
}

תוכניות לדוגמה[עריכת קוד מקור | עריכה]

הדפסת ההודעה "Hello world":

print("Hello world")

-- Lua allows to call functions without parenthesis when there's only one parameter:
print "Hello world"

הערה בת שורה אחת מתחילה בזוג מקפים. הערה בת שורות אחדות מתחילה בזוג מקפים ואחריהם זוג סוגריים מרובעים, ומסתיימת בזוג סוגריים מרובעים (כך נכתבת הערה גם ב-SQL). Lua מאפשרת גם קינון הערות מרובות שורות בעזרת הכלת התו ‚=’ באופן מאוזן בין הסוגרים המרובעות בכל אגף.

-- A comment in Lua starts with a double-hyphen and runs to the end of the line.
--[[ Multi-line strings & comments
 are adorned with double square brackets.]]
--[[ Level 1 fold
 --[==[ Level 2 fold
 --[===[ Level 3 fold
        --]===]
    --]==]
  ]]

לולאת for:

-- Plain for loop:
for i = 1, 5 do
 -- Statements
end

-- Loop through each item in a table. (simlar to "foreach" in other languages)
-- Since the keys are strings, the order of iteration is not guaranteed.
local days = {
  ["Sunday"] = 1,
  ["Monday"] = 2,
  ["Tuesday"] = 3,
  ["Wednesday"] = 4,
  ["Thursday"] = 5,
  ["Friday"] = 6,
  ["Saturday"] = 7
}
for key, value in pairs(days) do
 -- 'key' is a string that represents the actual index.
 -- 'value' represents `days[key]`, similarly `days["Monday"]` will return 2.
end

-- Loop through each item in a table, and count their index.
local days = {
 "Sunday",
 "Monday",
 "Tuesday",
 "Wednesday",
 "Thursday",
 "Friday",
 "Saturday"
}
for index, key in ipairs(days) do
 -- 'index' is a number, that can be used as `days[i]`.
 -- 'key' represents the actual item, ie. "Monday".
end

שגרה רקורסיבית לחישוב עצרת בלי ועם האופטימיזציה האופיינית לתכנות ב־Lua:

-- Naive recursion without cache is not recommended in Lua.
function factorial(n)
 if n == 0 then
 return 1
 else
 return n * factorial(n - 1)
 end
end

-- Recursion with a memoized cache table will make the function perform much faster in future calls, thus is strongly encouraged in Lua if the extra memory can be afforded during execution time.
local cache = {
  [0] = 0,
  [1] = 1
}
function factorial(n)
 -- Note that 0 doesn't evaluate to 'false' in Lua.
 if not cache[n] then
 cache[n] = n * factorial(n - 1)
 end
 -- Instant retrieval time for previously computed values.
 return cache[n]
end

פונקציות ב־Lua הן משתנים לכל דבר, וניתן להקצות להם שמות משתנים חדשים או להעביר אותן כפרמטרים.

-- Declare a local scope with `do - end` where the redefinition of `print` will be valid.
do
 -- Store the current `print` function as oldprint
 local oldprint = print

 -- Redefine the `print` function
 local function print(message)
 if message == "foo" then
 oldprint("bar")
 else
 oldprint(message)
 end
 end

 -- Test the new override:
 print("Hello world") --> Hello world
 print("foo") --> bar
 oldprint("foo") --> foo
end
-- Once exiting the `do - end` scope, `print` reverts to its original meaning.
print("foo") --> foo

מימושים עיקריים[עריכת קוד מקור | עריכה]

מהיותה שפה זעירה וחופשית שנועדה לשיבוץ, ל־Lua קיימים מימושים רבים שפותחו במשך השנים למגוון מטרות שונות על ידי מפתחים וצוותים עצמאים.[4][5] בין המימושים קיימים הבדלים ואי־תאימויות לאור המגבלות שמולן הם נעמדו או עקב שינויים ללא תאימות לאחור שחלו במימוש הקנוני של Lua מהאוניברסיטה הקתולית (PUC Rio).[6]

מצב זה העמיד קושי לקהילת החופשית של Lua ולמיזם מערכת ניהול החבילות שלה (LuaRocks) לנסות ליצור שיתוף פעולה ותיאום בין החבילות הזמינות שהציעו מפתחים מול הגרסאות השונות של השפה שחלו במימושים המועדפים עליהם.[7]

בסביבות 2015 הקהילה התפצלה לשני מחנות מרכזיים והם Lua 5.3 ו־Lua 5.1 עקב ההתנגדות הנחרצת שהביע היוצר של LuaJIT מליישם את השינויים החדשים של Lua 5.3 ב־LuaJIT לאחר שכבר הביע התנגדות קודמת לשינויים של Lua 5.2 אף על פי שיישם את חלקם.[8][9][10]

נכון ל־2019 רוב החבילות ב־LuaRocks זמינות בגרסאות Lua 5.3 ו־Lua 5.1 בעיקר כדי לשמור על תאימות לאחור עם LuaJIT, שהוא המימוש המועדף על חלק ניכר מהקהילה.

Lua (PUC Rio)[עריכת קוד מקור | עריכה]

זהו המימוש המרכזי והנפוץ ביותר של Lua ונהוג לעיתים לכנות אותו PUC Lua. הוא מפותח באוניברסיטה הקתולית (PUC Rio) שבריו דה ז'ניירו בברזיל מאז 1993 ומופץ תחת רישיון MIT.[6] PUC Lua הוא מפרש זעיר ודינמי הכתוב בשפת C,[4] ומצטיין בצריכה חסכונית של זיכרון וכוח עיבוד למרות ביצועיו המעולים ביחס לשפות מפורשות אחרות.[11]

PUC Lua ממיר קוד מקור של Lua ל־bytecode הסטנדרטי של השפה תוך כדי שהקוד עובר בדיקות ראשוניות כגון חוקיות תחביר לפני הריצה שלו. ניתן לייצא את ה־bytecode שנוצר לתוך קבצים מתוך הקוד בעזרת הפונקציה ()string.dump או מחוץ לקוד בעזרת הפקודה luac במסוף.[12]

LuaJIT[עריכת קוד מקור | עריכה]

LuaJIT הוא מימוש המכוון לביצועים גבוהים מאוד עם Lua בעזרת הידור תוך כדי זמן ריצה (Just In Time compilation), מפרש שחלקים ממנו כתובים בשפת סף, וממשק FFI (Foreign Function Interface) חדש לתיווך בין Lua ופונקציות ומבני נתונים הכתובים בשפת C בצורה טבעית מבלי לגרוע בביצועים של המפרש.

בנוסף למהדר, גם המפרש של LuaJIT הוא מהיר בהרבה מהמפרש הסטנדרטי של PUC Lua אפילו אם המהדר אינו מופעל כלל. היוצר מייק פּוֹל פיתח את המפרש של LuaJIT באופן עצמאי בלי לפצל את המפרש הסטנדרטי של PUC Lua.

LuaJIT מעודדת את המתכנת להיעזר בפונקציות וספריות הכתובות בשפת C במקום להיעזר בספריות צד שלישי הכתובת ב־Lua. ממשק ה־FFI של LuaJIT מאפשר גישה ושימוש טבעי עם ספריות, מבני נתונים ופונקציות מספריות בשפת C בלי לגרוע בביצועים שלה וגם מבלי צורך להיעזר ב־Lua C API כפי שדרוש במימוש הסטנדרטי של PUC Lua.

הביצועים של LuaJIT לעיתים קרובות מהירים משל PUC Lua 5.1 עשרות מונים.[13] מה שהפך את המימוש לאטרקטיבי עבור מפתחים שנשענים על ספריות גרפיות, יישומי רשת, טכנולוגיות ענן,[14] וחברות תקשורת גדולות.[15]

eLua[עריכת קוד מקור | עריכה]

eLua (קיצור של Embedded Lua) היא מימוש מלא של השפה המיועד למערכות משובצות מחשב ומציע אופטימיזציות והרחבות חדשות לשפה שהן רלוונטיות לחומרה האופיינית למערכות משובצות.

תכונות מרכזיות:[16]

  • שליטה מלאה וישירה בחומרה שעליה היא רצה, מאחר שאין אף נוכחות של מערכת הפעלה במערכות משובצות. עם זאת המימוש נמנע מלהפוך לתחליף עבור מערכת הפעלה.
  • תאימות הקוד על מערכות משובצות בעלי ארכיטקטורה שונה וחומרה מגוונת. המימוש של eLua דואג למגר כל הבדל אפשרי בהתנהגות השפה על גבי מעבדים עם סט פקודות שונה.
  • המימוש מתוכנן בקפידה כך כדי לאפשר החלפה ושדרוג מזדמן של החומרה מבלי לגרום לאי־תאימויות בקוד שנכתב עד כה.
  • מעטפת המאפשרת אינטראקציה נוחה בתהליך הפיתוח בין הקוד המשובץ לקוד שנערך על ידי המשתמש, כמו למשל שיבוץ וניסוי הקוד וקבלת משוב על שגיאות בקוד תוך כדי זמן הריצה בלי צורך בסימולציות לפני השיבוץ.


קישורים חיצוניים[עריכת קוד מקור | עריכה]

ויקישיתוף מדיה וקבצים בנושא לואה בוויקישיתוף

הערות שוליים[עריכת קוד מקור | עריכה]

  1. ^ Hisham Muhammad (יזם LuaRocks), מעקב שינויים רשמי של מערכת ניהול החבילות של Lua באתר GitHub., github.com
  2. ^ הנתונים סטטיסטים של LuaRocks, luarocks.org
  3. ^ העמוד הרשמי של LuaRocks, luarocks.org
  4. ^ 4.0 4.1 Lua is small, עמוד הבית של Lua
  5. ^ lua-users wiki: Lua Implementations, lua-users.org
  6. ^ 6.0 6.1 Version history, עמוד הבית של Lua
  7. ^ Tim Mensch, Fragmentation of Lua, RealMensch
  8. ^ Extensions, luajit.org
  9. ^ My love-hate relationship with LuaJIT (2015) | Hacker News, news.ycombinator.com
  10. ^ Fragmentation of Lua, RealMensch
  11. ^ Lua vs Python 3 - Which programs are faster? | Computer Language Benchmarks Game, benchmarksgame-team.pages.debian.net
  12. ^ luac man page, www.lua.org
  13. ^ Performance: x86/x64, luajit.org
  14. ^ LUA, The Cloudflare Blog (באנגלית)
  15. ^ LuaJIT Sponsorship Program, luajit.org
  16. ^ Overview - eluaproject, www.eluaproject.net