Convenience. Because it is largely used to "construct" new objects (in the manner of OOP for example), the first argument to setmetatable
is very often an (empty) table literal. See PIL code of an example.
This convenience lets you write
local set = setmetatable({}, Set.mt)
instead of
local set = {} setmetatable(set, Set.mt)
PiL explains that fairly nicely: https://www.lua.org/pil/16.html
But a TL;DR: In function declarations, using a colon adds a first parameter named "self". Those two below are completely identical:
local foo = {} function foo.bar(self, a, b, c) end function foo:baz(a, b, c) end
In function calls, and only where you call a function you index from a table, using a colon automatically passes the table itself as the first arg. See below:
local foo = { run = print } foo.run(1, 2, 3) --> 1 2 3 foo:run(1, 2, 3) --> table: 0xdeadbeef 1 2 3 print(tostring(foo) == 'table: 0xdeadbeef') --> true
Get yourself a project that uses Lua, or a Lua library like lua-posix. You'll just have to look at the structure of the code to get a good impression. Then read through the reference manual top to bottom [1]. If you need some more hints, the oldest edition of Progamming In Lua (targetting 5.0 but still relevant in large parts) is available for free [2]. Now, go back to your example project and try to understand parts of it, and then all of it.
Coming from a C background, what I had to write Lua<>C interops for was understanding how exactly upvalues work. But that's already an edge you're unlikely to touch if you don't exactly want to.
This, plus writing actual code, was all I personally needed.
> Also, do I need to learn another language before I can do this or to help me learn this?
It would be helpful to know some general concepts, but the materials in [1], [2] explain things by starting with the basics and then putting them together, so if you're really interested in engaging the subject you'll have a fun and productive learning experience even without prior knowledge.
[1] https://www.lua.org/manual/5.3/ [2] https://www.lua.org/pil/contents.html (I also recommend the paper book, if you want to afford it).
Programming In Lua is really great as a reference manual.
https://www.lua.org/pil/contents.html
If you like Minecraft, I recommend the mod CC:Tweaked (continuation of ComputerCraft). It's a lot of fun to play with and is substantially easier to learn compared to OpenComputers.
I'm a proponent of sketch out the thing you want to make and then learn just enough to be dangerous, but if you want some resources that are better written than anything I could make on the spot:
https://love2d.org/wiki/Category:Tutorials
Love2d is a game framework for lua and so that is an ok place to start.
But there is no perfect tutorial so asking questions early and often is good (and having a specific goal in mind helps ask better questions). Especially since tutorials can't guess at what skill level you are currently at.
/r/love2d for future reference
You're close. Formatting your code to fit on a single line makes it difficult to read, here's what it looks like formatted:
function stripecircle(r, x, y) for dtheta = math.pi, 0, -math.pi/512 do index = 0 if index%0 == 0 then love.graphics.setColor(1, 0, 1) -- set color to violet index = index + 1 love.graphics.line(rmath.cos(dtheta) + x, rmath.sin(dtheta) + y, rmath.cos(-dtheta) + x, rmath.sin(-dtheta) + y) else love.graphics.setColor(.5, .5, .5) -- set color to gray index = index + 1 love.graphics.line(rmath.cos(dtheta) + x, rmath.sin(dtheta) + y, rmath.cos(-dtheta) + x, rmath.sin(-dtheta) + y) end end end
The issue is that a new index
variable is created for each iteration of the loop. This is incorrect, you want a shared variable so each iteration will be reading and updating the same value. Something like:
function stripecircle(r, x, y) local index = 0 for dtheta = math.pi, 0, -math.pi/512 do if index%0 == 0 then love.graphics.setColor(1, 0, 1) -- set color to violet else love.graphics.setColor(.5, .5, .5) -- set color to gray end love.graphics.line(rmath.cos(dtheta) + x, rmath.sin(dtheta) + y, rmath.cos(-dtheta) + x, rmath.sin(-dtheta) + y) index = index + 1 end end
I haven't tested it but I think that should get you what you want.
I think the actual reason is history. They had two languages, realised they could combine them into a single new language, and created Lua from them. The predecessors didn't have local variables, so Lua ended up global-by-default.
I think it's a bad decision and local-by-default is the only sane choice, but it is what it is. It's a product of its time, because Lua and its predecessors were created at a time when bad defaults and footgun features were the norm because the language isn't supposed to hand-hold when you can just not make mistakes. The interest in having safe defaults and bug-prone features being opt-in instead of opt-out is a more recent thing in PL design.
> Lua has an official github repo.
> The Lua repo, as seen by the Lua team. Mirrored irregularly.
I'd say that's pretty much not official in any capacity. The official place to get the source code is the FTP source. Alternatively, all source pre-releases can be obtained from the working space.
> according to google, doing + should work but it always syntax errors
Not sure what you're searching to get that impression but +
is an arithmetic operator in Lua and is not used for string concatenation. If you search for "Lua string concatenation" (correct) or even "Lua string addition" (technically wrong) this page should show up high in the results with the correct operator: ..
You want to do "foo" .. "bar"
Easiest way imo to start with Lua is with ZeroBrane Studio...
Download it, run it, type some code and hit F5 to run/debug or F6 to just execute the code (there are buttons for those actions too).
Either use https://studio.zerobrane.com/ or write a plugin for https://github.com/Alloyed/lua-lsp on Vim. Not really sure about any other options.
I'm a savage who blindly writes code without that stuff, so sorry if I missed something.
Here's something funny I found out messing with it: if you go here: https://www.lua.org/cgi-bin/demo?demo you can see some of the code executed in the backend, and it also breaks the html. Actually, it searches for anything you write after the "?" in the url.
Someone should probably warn whoever maintains the website, there's some insecure code in there...
This code is illegal because the lua grammar doesn't allow arbitary expressions as statements. Valid lua statements are function calls, assignments, function/variable declarations, for loops, if statements, etc
Programming in Lua and the Lua Wiki Tutorial are my recommendations.
Lua is a general-purpose programming language, so it can be used for any purpose which is my Lua is also used to create games (and websites, etc.). The standard libraries (built-in functions) are very basic though, so you're going to need some kind of reference specific to your usage.
according to this https://www.lua.org/manual/5.3/manual.html#3.4.10 You are wrong. "A call of the form f'string' (or f"string" or f[[string]]) is syntactic sugar for f('string'); that is, the argument list is a single literal string."
If you're not specifically wedded to the idea of using Lua for this, Godot is worth considering as well. It uses its own Python-like language that seems pretty easy to use and provides a lot more "game engine" things out of the box, with a pretty intuitive (IMO) node system and a usable UI for working with everything. (You can technically use Lua with it if you compile things yourself, but that's probably out of scope for you since you're asking something like this; better to stick with the built-in language.)
I think the closest thing to Godot you'll find for using Lua would be Defold, though it seems to do less. Love2d has been around forever and is mature, but is less "game engine" and more "framework for implementing a game engine".
Depending on what your game idea is, you could also use one of the Lua-based "fantasy consoles" like TIC-80, PICO-8, or Pixel Vision 8. They're sort of like video game console emulators, except for hardware that never existed. Retro feel with limited resolution and sound capability, built-in Lua editors, and a bunch of stuff to help make implementing things easier.
Thanks for posting this. It reminds me a great deal of all C++ frameworks like Cinder and openFrameworks. If I could afford to be retired, these are the things I would be playing with for months at a time.
You have the editor vim already installed, it has syntax highlighting, but is not that easy to work with for a beginner. I use it myself, but it might not be the best choice for you.
Another option is to use textedit, but that one lacks any support for syntax highlighting at all. Be sure to set the text type to plain text (format->plain text) and to change the extension to .lua instead of .txt.
I also heard a lot of positive feedback about TextWrangler. It has syntax highlighting for Lua, but I never used it myself.
A more complete list can be found here.
I knew someone was going to say that, though I came to the comments to make the same joke just in case nobody already had. :)
If that's what OP wants to use, nothing wrong with it. It at least syntax highlights so it's better than notepad, which a lot of people use especially early on.
Though I'd suggest at least trying micro out instead. It's similarly newbie-friendly, but has more features, its shortcuts are more like modern applications (ctrl-s to save, ctrl-f to find, etc.), and is extensible with Lua. Still not necessarily the endgame choice for programming but a good step up while having a low learning curve. Should be in basically every distro by now too, so apt install micro
(or whatever your distro's equivalent is) and you're good to go.
I recommend using defold it's a free open-source (kinda) cross platform game engine.
If you want a retro fantasy console emulators then TIC-80 and PICO-8 are the best options imo (PICO-8 is proprietary software that you have to pay for, but TIC-80 is open-source), but they are mostly code based with a few interactive tools (like a world editor).
​
There are also the most popular ones, like Love2d and solar2d (prevoisly named Corona) but those are frameworks and not a game engine (they both don't have world editors or anything like that)
To download the Lua binaries, head to https://www.lua.org/download.html.
​
They have pre-built binaries and source to build from with their respective Makefiles included for several different versions.
I usually go straight for the reference manual. You can find stuff pretty quickly with ctrf+F: https://www.lua.org/manual/5.3/manual.html
I don't know if someone made a neatly formatted "cheatsheet-style" reference for 5.3 though.
You are essentially asking for a way to convert a function into a human-readable string. This is pretty difficult in most programming languages, including Lua.
However, the exact opposite of your request is pretty easy: you can convert a human-readable string into a function using <code>load</code>.
s = "print('Hello')" a = load(s) a() -- Hello print(s) -- print('Hello')
So if you are looking to print the content of functions that you have written yourself, load
might help you.
You should be aware that if you are running Lua inside someone else's application (ex. in a game), the developers may have disabled load
. When making an application of your own, you should also recognize that running load
on a string that your users may have tampered with can be very unsafe (much like eval
in certain other programming languages).
the function setmetatable
returns the table.
https://www.lua.org/manual/5.3/manual.html#pdf-setmetatable
>setmetatable (table, metatable) > >Sets the metatable for the given table. (To change the metatable of other types from Lua code, you must use the debug library (§6.10).) If metatable is nil, removes the metatable of the given table. If the original metatable has a __metatable field, raises an error. > >This function returns table.
(btw, Lua isn't an acronym).
It absolutely can be used as a standalone application. The Prosody XMPP server is a great example of that.
The main thing against it is, as Ubertekk stated, the fact that there aren't as many readily available high quality libraries for lua as there are for perl or python or ruby (or whatever) so there is likely to be a cost associated to going this route that there might not be going with other languages or embedding lua.
One other point, many things that "embed" lua are actually just getting things set up to the point that lua can take over and then most of the application/etc. happens once lua has been brought into play.
I concur with mbone on the try it and see, but you also have the option to install the lua51 package, and then specify the path to the lua 5.1 binary. Would be potentially easier than retrofitting 5.1 into 5.3.
It's a bit complicated in the sense that you need a kind of debug stub in your application - there's no Lua built-in for external debugger access, this missing link between debugger and (Lua) code has to be integrated into your application, too. I am assuming here that you use Lua within your application, interconnected with the rest of the code by using the Lua API.
Thus, every solution you might encounter is a bit proprietary in the sense that it will be fit for a certain debugger only. For Zerobrane, this is documented here: https://studio.zerobrane.com/doc-remote-debugging
I'm the author of the Haxe Lua target. It's still very new, but I believe it can help Lua grow, and keep long time Lua folks from jumping ship to a completely different ecosystem.
Haxe is in many senses a very different language than Lua, but it addresses many of the authors complaints:
I'm not going to pretend that the Haxe and Lua languages are related, but I think Haxe is a very promising way of building more sophisticated Lua based applications. E.g., It is now possible to use one language to target an nginx/lua, redis/lua, and javascript stack. In fact, that's what I'm going to try and work on in the near future here.
It sounds like you either have no programming experience or no Lua experience. Which is it?
Here's how this example would be coded in Lua:
p = { {x = 0, y = 0}, {x = 0, y = 0} }
function setX(player, x) p[player]["x"] = x end
function setY(player, y) p[player]["y"] = y end
Here's an example, just load the page and click run
This depends entirely on the rendering engine. Font, size, etc. all come into play. So, for example, LÖVE has Font:getWidth and Garry's Mod has surface.GetTextSize. Whatever API you use which supports this function would be different. However, they would probably already have wrapping support built-in if they already support this (just like LÖVE and Garry's Mod)
If you are interested in game programming, Love2d is a great framework. I recommend it everyone doing game programming as it is a super lightweight way to prototype game ideas.
I also recommend it, it had few versions of Lua available for general purpose scripting (LuaJIT, Lua 5.2/5.3) as well as some Lua based frameworks like Love (https://love2d.org/, wiki link in top left) which is amazing for 2d games or other apps made for fun. Everything working out of the box of course.
That's the way locals have always worked in Lua. <const>
is really just an offshoot of the <close>
attribute, so it only supports as much constant-ness as is required by a to-be-closed variable. https://www.lua.org/manual/5.4/manual.html#3.3.8
The matching is trying to be "clever" by escaping the special characters used by Lua's pattern matching. (ref). One of these is "-"
so it would be escaped as "%-"
. The gsub
is meant to do that, except it changes it to "%%-"
instead. (My guess is this was translated blindly from a C-like language which uses backlash rather than percent, and to use a backslash in a string requires double-escaping.)
A solution is to change every "%%-"
to "%-"
. However, there's a better way. If you don't intend to use pattern matching, and are only looking to search for plain substrings, the find
function has a flag that turns off the special character handling. (ref) So that line would look like...
if iconpath:find(ICON_OVERRIDES[icons.appname], 1, true) then
As you can see, the extra call to gsub
is not needed. The other uses of find
can be adjusted accordingly.
Lua does not particularly have any serious bugs (that you will encounter). if you have a package, use the package manager, the latest lua version is not 5.3 but 5.4. so this is just a needless headache you're dealing with.
if you want to see the bugs, here they are: https://www.lua.org/bugs.html
Time is never a "beginner" question. See http://www.creativedeletion.com/2015/01/28/falsehoods-programmers-date-time-zones.html
From the manual: https://www.lua.org/manual/5.4/manual.html#6.9
> os.date ([format [, time]])
> if format is the string "*t"
, then date returns a table with the following fields: year
, month
(1–12), day
(1–31), hour
(0–23), min
(0–59), sec
(0–61, due to leap seconds), wday
(weekday, 1–7, Sunday is 1), yday
(day of the year, 1–366), and isdst
(daylight saving flag, a boolean).
So that gets you the components of the time. Then test the min
and hour
fields.
return (min >= 58 and hour%2 == 1) or (min < 4 and hour%2 == 0)
https://www.lua.org/pil/ They have several official books, of which the oldest is 100% free online, but is slightly more outdated (It is 5.0 instead of 5.3 like the 4th edition).
As for WoW addons, honestly just using the various documentation online for the WoW API mixed with normal Lua is enough to get started on it.
Concatenation has performance issues if you do so inside a long loop.
The exact reasons are explained in Lua Performance Tips, page 8 of the pdf.
How to solve? Use table.concat.
The original poster makes a good point. Without knowing what you’ve done, its really hard to find what you are looking for.
With a google search, I was able to find the original Lua interpreter tests. https://www.lua.org/tests/ These can be used to test your interpreter. Have you done this yet?
Use pairs/ipairs
https://www.lua.org/pil/4.3.5.html
local t = { ["key1"] = "value1", ["key2"] = "value2", } for k,v in pairs(t) do print(k.." = "..v) end
local ti = { [1] = "value1", [2] = "value2", } for k,v in ipairs(ti) do print(k.." = "..v) end
In Lua, binary data is usually encoded as a normal string. Unlike in C, this works without problems as Lua strings aren't 0-terminated. It shouldn't be much of a problem to keep track of your padding that way, as the length of a string is not only its length in characters, but also its length in bytes, and you can convert between numeric values and string representations using string.byte()
(reference) and string.char()
(reference).
If your networking library takes care of converting the data to hex for you, I really recommend just making use of that instead, and doing all your other magic on the binary string. If you have any trouble with that feel free to come back and ask more questions :)
BTW: most of the questions here seem to be from people who are either new to Lua or completely new to programming, and I don't think people care at all about how silly they may get (And trust me, people have asked some pretty weird questions)
It actually is. Functions that take a single string literal or table constructor argument can have their parentheses omitted at the call site.
>A call of the form f{fields} is syntactic sugar for f({fields}); that is, the argument list is a single new table. A call of the form f'string' (or f"string" or f[[string]]) is syntactic sugar for f('string'); that is, the argument list is a single literal string.
well there is no difference between
if ( (a == 1) and (b == 2) ) then
and
if (a == 1) and (b == 2) then
because Lua doesn't require parenthesis around the expression.
The remaining parenthesis can be left out too because ==
has a higher operator precedence than and
and so
if a == 1 and b == 2 then
does the same. The PiL manual has the full operator precedence table:
>Operator precedence in Lua follows the table below, from the higher to the lower priority: > > ^ > not - (unary) > * / > + - > .. > < > <= >= ~= == > and > or
^^https://www.lua.org/pil/3.5.html
and on the bottom there's a note: >When in doubt, always use explicit parentheses. It is easier than looking up in the manual and probably you will have the same doubt when you read the code again.
This is the reason that I personally would put parenthesis around the two sub-expressions (but not around the whole expression because that's just wasted characters and doesn't clarify anthing).
I used the manual: https://www.lua.org/manual/5.3/manual.html
But it sounds like you are new to programming, you may want to look for material specifically targeting someone who has never programmed before.
This question is way too vague. What exactly are you trying to do? Which things are you trying to pick out of a text variable? Do you mean a string?
If you're looking for ways to manipulate strings, what is provided is all in the string library.
What operating system are you trying to install it for? How are you trying to install it?
On many systems, the easiest way to get Lua is to download the source and build it yourself. This is easier for Lua than most applications that tell you to do this because of how portable Lua is.
Follow the directions on this page https://www.lua.org/download.html in the section called "Building". If you're on Windows, you'll either need to use Bash on Windows, or use Cygwin/MinGW.
functions declared with the colon do implicitly have self as the first argument. "The colon syntax is used for defining methods, that is, functions that have an implicit extra parameter self. Thus, the statement
function t.a.b.c:f (params) body end
is syntactic sugar for
t.a.b.c.f = function (self, params) body end
"
The key and the value. See PIL Chapter 7.3.
Beware: this part of the the online version of the book is valid, but large parts of the rest are outdated. Fetch a recent copy at your local library/bookstore/hackspace/... if you want to learn Lua.
How about:
Store the numbers (or pointers to the numbers) as userdata
Expose some C functions to Lua that operate on this userdata
Write a Lua package that acts as an interface to the previous 2 parts
Works fine on repl.it, so the code isn't the problem, something else is. You should give some information about your environment for troubleshooting purposes, and also do what /u/Saldor010 said to verify that you can print anything.
So anytime I see one of these "do this without using assignment" things I roll my eyes because it's usually some Haskell author trying to bait. And the answer is always either "use a monad" or "use the Y-combinator". In this case, it's the later.
But as I started to type the solution I noticed another catch. To truly avoid using variables you cannot create any named function, since
function FOO() end
is
FOO = function() end
Nor can you use function arguments:
function (foo, bar) end
is compiled as
function (...) local foo, bar = ... end
But it's still possible and quite easy, actually. So, here it is. I was using =
to assign to the table until I opened the thread and saw the comment about rawset
.
If you look here (note it's in the Lua53 subfolder), the Win32 zip seems what you're looking for. It contains the Lua executables + IUP dlls.
Ideally, error and x/pcall. If you really do not want to deal with proper exception handling, you can do it with message passing through coroutines. I’ll write you a little example in a few hours.
edit: Here's an edit of yours that seems to do what you want? https://hastebin.com/ekorovigup.lua
It doesn't rely on exception handling and it should be pretty easy to make changes to.
> There's not really any functions I find myself reaching for over and over that are (1) large enough for me to keep save somewhere and (2) general enough that they truly don't need tweaking between projects.
1) Size doesn't matter, rewriting the same functions over and over is pointlessly tedious.
2) Lua's a pretty good language for functional programming style, which relies heavily on functions that are general enough that they don't need tweaking. Higher-order functions like map
, filter
, and reduce
can always be reused.
Unfortunately, Lua doesn't provide any of the expected basic FP functions on its own, so you have to implement them yourself (or copy code from someone that did). That's how I ended up with my own small collection of FP staples that I reuse whenever I use Lua for something.
A few things that can be changed:
deep_replace = function (table, search_for, replacement)
Can be written as
local function deep_replace(table, search_for, replacement)
​
This line doesn't either do what you want it to:
if table == false then return nil end
It will only end the execution if table
is actually false
. If table
is just missing, it will run regardless.
You could replace it with either of these lines:if not table then return end
if type(table) ~= "table" then return end
(In neither case do you need to specify that you return nil
, as that is the default)
Now the biggest change that you could make would be to change the table in place. When you pass a table to a function, it is actually passed as a reference. This means that if you edit table
from within the function, it will edit the one outside as well.
This might not be desirable, of course, but if that is what you want, then you could do this:
local function deep_replace(table, search_for, replacement) if not table then return end
for key, value in pairs(table) do if type(value) == "table" then deep_replace(value, search_for, replacement) else table[key] = value:gsub(search_for, replacement) end end end
local my_table = { foo = 'bar', t = { tfoo = 'tbar', tfoot = { ttfoo = 'ttbar' } } }
print(my_table.foo) print(my_table.t.tfoot.ttfoo)
deep_replace(my_table, 'bar', 'blerg')
print(my_table.foo) print(my_table.t.tfoot.ttfoo)
https://repl.it/repls/VastOddStruct
EDIT: Forgot to mention, it will crash if the table contains any numbers at all, since it tries :gsub()
on anything that isn't a table.
Lua can handle most tasks standalone and is worth learning because of its simplicity and performance.
Embedding makes sense for some specific tasks, but it almost never requires any extra effort or even knowledge of other languages.
For example lua doesn't support multithreading and if you want to write complex games you better use thread module from an game engine like love2d; if you are writing a webserver you can use lapis or similar framework. In all those cases you don't need to know any other languages than lua.
What "function docs page" were you looking at? The actual manual has this basically as the first information following the general function call syntax in the "function calls" section: https://www.lua.org/manual/5.4/manual.html#3.4.10
I've never seen or heard of Textadept, so thanks for introducing me to it. I will check it out sometime. Superfically it looks similar to Howl but that's based only on a quick glance; I'm sure there are significant differences between the two.
> How does your editor compare to it?
My editor of choice is GNU Emacs, and even though I've never used Textadept, its official site describes Textadept as "minimalist", which no sane person would ever use to describe GNU Emacs, heh.
choco install <program>
, for instance choco install lua
.Note that i wrote this stuff here implementing the idea of taking over require
and recording/limiting what is available.
It is still experimental, eventually i'll apply it on my code. Maybe make some graphs using <code>dot</code>.
I do think that in principle, you can do crazy stuff, like taking one of the files, and saying "this runs on this other server".
I just got ZeroBrane's remote debugger to work with my game in about 30 minutes, following their official guide. Basically it was setting a flag in Zerobrane's menu, adding
package.path = package.path .. ";C:\Program Files\ZeroBrane\lualibs\?\?.lua;C:\Program Files\ZeroBrane\lualibs\?.lua" package.cpath = package.cpath .. ";C:\Program Files\ZeroBrane\bin\clibs52\?\?.dll;C:\Program Files\ZeroBrane\bin\clibs52\?.dll" require('mobdebug').start()
to the lua file I was trying to debug, and it basically worked.
Haven't done much more with it since getting it going but it worked and I was stoked.
You have good intentions but this seems misguided. Once you do that, you've made it practically impossible for anyone using your language fork to use any online resources; whereas with the original language, even if they can't understand the surrounding discussions, they could at least find code snippets and experiment with them. You'd be making things worse.
Furthermore, even if the words resemble or are equivalent to a spoken language, you have to remember that a programming language still isn't English or any other language. Sometimes the keywords match up to their expected English meaning, but that's not a guarantee that should be relied on. For example: map
and fold
don't quite match up to their most commonly-used English meanings, and worse still, map can either be a function or a data structure (or both) depending on the language; some words like lambda
are rarely seen outside of mathematics or programming; and sometimes English expectation is completely counter-intuitive, like OCaml's anonymous functions using the fun
keyword, which has meaning in English that doesn't match the language use.
Reading code is more like reading music than prose. You learn what the symbols mean and how to use them, and translate that into something you understand as you read them.
That said, if you're determined to try it, you can go a long way with C preprocessor directives. The original Bourne shell was written like this, using #define
liberally to turn C into something more like Algol. Localising keywords is trivial incomparison. Racket, a Scheme dialect, has the ability to define custom languages and language extensions and use them by adding #lang foo
at the top of source files, so you could make a translator for it as well.
Still, I think it's a well-meaning but poorly thought out idea.
> ... but it lacks support for (for instance) forms which bind variables monadically (rather than in the identity monad).
I've got some previous Haskell experience, but didn't quite understand this bit. Do you have an example of what you'd want to accomplish but can't seem to with the base Lua semantics?
While being previously quite enamored with the ideas underlying Haskell, I've drifted away from purity and laziness. I had a hard time to learn how to re-compose problems to suite the natural structure of Haskell code. And, actually, dealing with state in video games. It seemed most practical solution was to conglomerate all the state together, and keep passing that through to the next iteration of the main loop.
I did look at FRP as well, but had issues with that.
> Is there an s-expression front end for lua which would dispense with these concerns (besides the one I am writing, which is 60% done)?
I haven't heard of anything like that. I'd guess that most of the people who would have wanted that were instead diverted to Metalua and its macro system instead.
At any rate, xolox's reply below should be some help, and I second what was said there. It might be possible to re-compile LÖVE to use Metalua (if that can be a regular dynamic library). Combining those with LuaJIT is definitely not going to happen in the near term.
Otherwise, I agree that source-to-source translation would be the best way forward.
It looks like you forgot to put a source type in your call to newSource: https://love2d.org/wiki/love.audio.newSource
You may want to check if music was set correctly with something like:
music = love.audio.newSource("somethinghere.wav", "stream") if music then music:setLooping(true) music:play() else print 'love.audio.newSource was not successful!' end
You can totally do this with lua - you'll probably want to just go ahead and learn how to use sockets. There might be a simpler way to do it since your project doesn't require actual network communication, but with sockets you'd have the option of chat over the internet, and it's a good way to learn about client-server architecture.
This tutorial is the only one I have at hand - I'll have more time to search later (and you can search for "lua socket tutorial" on your own as well.)
I took the Lua code from here and updated the Mersenne Twister part to use Lua 5.3's builtin bitwise operators which increased the speed tremendously.
But it's still slower than multiply-with-carry which is what I'm now using. Here's a link to the current version I use.
I see no reason why this shouldn't work the same on any platform. But it would be nice to see that confirmed! And I would love to improve the performance of the code if you have any ideas for optimizations.
It could be a bit of a chicken and egg problem. W/o having a generational collector maybe apps that could be enabled by it won't be written. Thus they can't find a corpus of pure Lua apps to test it with.
It doesn't seem like there is something like a garbage collector benchmark suite that models different kinds of garbage generation.
The best existing applications that I think would benefit from a generational collector would be video games, but LÖVE is mostly C++ code.
I suppose we can differentiate between Lua's semantics and what's actually stored in memory. Since Lua reads the global aetoidlpcubjcboaubkxukac
as nil
, that variable does exist semantically, even though it's not stored in the _G
table.
> Not just a table thing, either, it deletes locals as well.
Actually, locals always occupy a spot in memory, even if they're nil
. They can't be deleted except by going out of scope, as this code shows:
x = 56 print(x)
local x = 30 x = nil print(x, _G.x)
Output:
56 nil 56
nil
doesn't just mean that there's nothing there. It's a proper value in its own right. It can be stored in local variables. select('#', ...)
can tell you exactly how many arguments are in ...
, even if they're all nil
. In Lua's C API, lua_type
[0] distinguishes between nil
and an invalid value. You just can't store it in tables. Or to flip it the other way, all table keys are nil
unless specified otherwise.
> That's actually one of the reasons I'm not a fan of Lua's behaviour with nils, because it's subtly magic and can lead to faulty assumptions.
I think it's fair to say that it's only confusing if you assume that all valid values must be stored in memory somewhere. For that reason, Lua's treatment of nil
might arguably be a design flaw, but purely from the standpoint of conceptualizing your data, there's nothing wrong with it.
Like other commenters have said, var
can be of any type, because in Lua:
nil
or false
is true
.and
returns its first argument if it is false
, otherwise it returns the second argument.Here's the reference in Programming in Lua book.
> I think ipairs(t) is fine as long as there are no nils in t at the time of calling it
This is true because ipairs
is going to call #t
once and only once before iteration, then reference that value during iteration.
> #t can get really weird and inconsistent with nils at just about any time, though.
It is inconsistent, but not weird at all. The inconsistency is very well specified, an inevitable consequence of how length is calculated.
lacethespace's answer is the right one. When matching whole strings against exact literals, you probably don't want regex.
> Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems. > > --Jamie Zawinski
But if you're trying to learn about patterns you could do it with captures and optionals:
for i,text in ipairs({"", ":", ": ", "hi:", ": hi"}) do -- wrapped in ^$ so we match the whole string. -- can't use ? on a capture, so we use it directly on : and %s. print(text, '|', nil ~= text:match("^(:?)(%s?)$")) end ---Results--- | true : | true : | true hi: | false : hi | false
Lua's regex is very limited (no OR, no back references, no modifiers on captures, etc), but it still can be quite useful. Read more details in the user guide. Be sure to look at the two tables of special characters.
Check out the relevant section of the manual: https://www.lua.org/manual/5.3/manual.html#3.3.5
Consider what these expressions return:
iter(a)
returns a new anonymous iterator function each time
iter(a)()
always returns 2, because it constructs a fresh iterator function, takes its first element and returns it
The for loop repeatedly invokes the first value passed to it (it's a bit more complex than that) until it returns nil.
In the first case, this first value is the anonymous iterator function (as it should be)
In the second case, the first value is a
itself, which gets repeatedly called until it returns nil, but since calling a
always returns 2, the loop goes on forever.
Technically, require
can load binary compiled files - it just doesn't like the extension by default, as it looks for .lua
files specifically. If you append ./?.luac
(as well as luac
versions of the rest of the entries) to package.path
, you can have require
look for .luac
files as well. AFAIK .luac
is an unofficial extension - there's no specific extension assigned for binary chunks, and I've seen .lua
used for binary files as well.
Specifically, Lua treats text and binary chunks the same when passed through load
(as long as the mode parameter is nil
/"bt"
). If it detects the binary chunk magic number (\033Lua
), it loads it as a binary chunk - otherwise, it tries to compile it as Lua source code. Since loadfile
doesn't modify the mode of load
unless otherwise specified, it too can load both types. And this passes down to dofile
, which is essentially loadfile
that calls the new function (except implemented in C). Finally, <code>require</code>'s Lua loader also uses loadfile
(more specifically, luaL_loadfile
) and doesn't specify a mode, so it can load both types as well, though it only looks for .lua
files as specified above.
TL;DR: Any loading function can run both binary and text source (as long as the mode isn't changed) - require
just can't see the extension. Rename the file or change <code>package.path</code> to allow .luac
files to be loaded.
You can use io.read "n"
as documented here: https://www.lua.org/manual/5.3/manual.html#pdf-file:read. On older versions you will have to use "*n"
instead of "n"
.
Lua does have type coercion, but not for all operations, such as comparison. From https://www.lua.org/manual/5.3/manual.html#3.4.4:
>Equality comparisons do not convert strings to numbers or vice versa. Thus, "0"==0 evaluates to false
I will have to test this out for myself and see how I can apply this to future projects because it seems like an excellent way to organize code. I've also been reading through the online version of the Programming in Lua book and it seems similar to concepts in chapter 15. Thank you so much for all the information you have provided, it is very insightful!
The Lua manual is a good start for all things in core Lua.
https://www.lua.org/manual/5.4/
The fact that you’re talking about events makes me wonder if you’re talking about a framework laid on top of Lua.
Heya,
I wanted to expand on something here that is explicitly wrong. Forgive my formatting also, this is my first post.
" Since it returns a Boolean value you can invert it with "not" or you can use the not equals operator, ~=. They're equivalent.
if not x == 5 then
end
Is the same as:
if x ~= 5 then
end
"
This is wrong, and it's a nasty gotcha. Go to https://www.lua.org/cgi-bin/demo and try this:
x = 10
if not x == 5 then
print("x is not 5 (1st test)")
end
if x ~= 5 then
print("x is not 5 (2nd test)")
end
The reason they produce different results is that the not
operator has a higher precedence than the ==
equivalence operator, so it gets evaluated first. So not x == 5
, or not 10 == 5
to substitute in the value of x, becomes false == 5
, as any value other than nil
or false
equates to true
when evaluated as a boolean, which not
will do. Therefore the equivalence test evaluates to false
, which is why the two if statements produce different results.
You would do well to develop an allergic reaction to anything that looks like not a == b
. As a general rule in situations where you can use the ~=
test, do so.
What exactly are you trying to do?
next
does <strong>not</strong> iterate over the table in any particular order. It could happen that it goes 2 => 1 => 3 for the table you listed.
Are you trying to just increment wrapping around from 1 => 2 => 3 => 1 => 2 => 3 => ...? If so, you can use i % #t + 1
.
Not aware of any shorthand for that. What do you expect print(next(t), 'test')
to print?
From the manual:
>Lua always adjusts the number of results from a function to the circumstances of the call. When we call a function as a statement, Lua discards all of its results. When we use a call as an expression, Lua keeps only the first result. We get all results only when the call is the last (or the only) expression in a list of expressions. These lists appear in four constructions in Lua: multiple assignment, arguments to function calls, table constructors, and return statements.
The thing about lua is theres a few different implementations of it. If you're using the C# NLua wrapper I know that pcall returns a special value (false, function) if there is a callback inside of it on some versions, and then you need to handle that. In the default implementation I imagine it would work exactly how you would expect since it pushes the function onto the stack then invokes it. PCall and load should just yield since they don't do anything that isn't thread safe around the calls, though pcall is handled very differently in basically every implementation (and same thing with xpcall). It's not documented asking for a yield, so I would personally treat it as explicitly undefined behavior.
As for the _yielding suffix, something like that is in my opinion easiest since it's not very commonly necessary to yield from an API function, and when you do need to yield from an api function you almost always need a corresponding synchronous version, and you need to name them differently. So it comes up naturally.
EDIT: I was wrong, pcall is documented to throw an error if you yield inside of an api call; that's what I get for looking a 5.1 reference & source code.
Excerpt from the manual
>...Lua raises an error whenever it tries to yield across an API call, except for three functions: lua_yieldk, lua_callk, and lua_pcallk. All those functions receive a continuation function (as a parameter named k) to continue execution after a yield.
> Regarding table[#table +1] = true: The # operator is actually not O(1) as you might believe. The size of the table (array) is not stored in lua. Instead it's O(log(n)) iirc.
Source?
In the source, tables contain a variable "sizearray." I'm just guessing, but I assume this is the size of the table. If I am in fact wrong, please explain why.
If you can "require" a C lib, you could load a function that does what you need. But my guess is that "requiring" a lib file will be also disabled/forbidden.
the official reference manuals are awesome. The wiki is not official, so it can be sketch at times but the manuals are detailed and accurate.
https://www.lua.org/manual/5.1/manual.html
https://www.lua.org/manual/5.3/
Another amazing source, but you'll need to know a bit of C is just reading the actual C API/interpreter source. It's extremely small and well written, even for a C noob it is understandable. When dealing with weird edge cases it is the definitive resource. If you want examples there is a guy who as done work in Love and is generally one of the most prolific people in the lua community imo look up a guy called lefo. He has some game jam entries on his GitHub and he also has a bunch of other interesting projects like a language that compiles to lua, a web framework for lua, and a blog that details how to use advanced language features.
It is "all in there" but some important things are literally one sentence. There is no fluff and it cannot be skimmed.
The Book is currently in the 4th edition and covers Lua 5.3.
The 2nd and 3rd editions are just fine and can be had used for <$10. Love uses LuaJIT which is a mixture of 5.1 and 5.2 features.
One example where this is useful:
> foo = {}
> function foo.setTable(t) table = t end
> function foo.useTable() print(table[1]) end
> A = {"green"}
> B = { "red" }
> foo.setTable(A)
> foo.useTable()
green
> foo.setTable(B)
> foo.useTable()
red
Which means, you customize the behaviour of foo. You don't need (and because of the unneccesary overhead also you don't want) a copy of the table for this.
Or take a look into the Chapter 16 of the lua manual about classes (https://www.lua.org/pil/16.1.html).
function Account:new (o)
````o = o or {} -- create object if user does not provide one
setmetatable(o, self)
self.__index = self
return o
end
a = Account:new{balance = 0}
Ignore the metatable stuff (line 3 and 4), and concentrate on the assignment of a table in line 2. Also here you don't want a copy the table {balance = 0}, that you only created for the construction of a new Account. And the function also returns a table that is assigned to a at the end, also here you don't want and need to copy the table.
Install Visual C++ 2015 Build Tools
Download and unpack Lua
Build Lua
cd C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC vcvarsall amd64 cd %USERPROFILE%\Downloads\lua-5.3.4\src cl /MD /O2 /c /DLUA_BUILD_AS_DLL *.c ren lua.obj lua.o ren luac.obj luac.o link /DLL /IMPLIB:lua-5.3.4.lib /OUT:lua-5.3.4.dll *.obj link /OUT:lua.exe lua.o lua-5.3.4.lib lib /OUT:lua-5.3.4-static.lib *.obj link /OUT:luac.exe luac.o lua-5.3.4-static.lib
local s = io.read() -- let's assume 1 2 34 4342 local t = {}
for number in string.gmatch(s, "[^%s]+") do table.insert(t, number) end
This iterates over the string and splits it into tokens that are inserted into table. You can then access the values by using:
>>t[3] 34
More read on this here:
Do you want to be able to manipulate the data or just to be able to pass it around?
Use userdatas for pointers, if the latter. Otherwise, you should create methods to manipulate the data in C, and expose that to Lua.
If you don't want to do that, you need to create a custom table, which is what I think you're suggesting (actually, it is what you're saying, but I'll keep the above text anyway). See below..
Part IV of PIL is an excellent resource. Give it a nice long read and try to understand what each snippet of code does, and what each method does.
You can use lua's built in hook mechanism from the debug library to set a function which is called every nth vm instruction. Before you run a user-defined script or function you can store the current time and check against it in the callback to see whether the allowed duration for the function has been surpassed.
If you already have some form of programming experience, I would recommend just diving into a project of some kind, and just looking up how to do things along the way. You may need to spend a bit of time on the Lua wiki, or on PIL (https://www.lua.org/pil/contents.html) in order to learn syntax, but lua is very easy to understand, so shouldn't be hard to pick up.
Since Lua is a scripting language, You need an interpreter, not a compiler.
You can either get the sources and build it Yourself from https://www.lua.org/ftp/ or just get a binary for Your OS from here http://lua-users.org/wiki/LuaBinaries or elsewhere.
You can take the "object-oriented" path. You will be able to know which "object" is using the function by using the reference "self".
For more info, check out: https://www.lua.org/pil/16.html
I don't have a Mac and I can't make the port to MacOSX, so if you want make the port, follow this steps.
How to make the port to MacOSX :
Download the latest version of SDLFW here : https://sourceforge.net/p/sdlfw/forum/Announcements/thread/a1d68404/
Go to /SDLFW/source/include/ : Edit "common.h" and enable the "MACOSX_PLATFORM"
Go to /SDLFW/source/_platform/ : Create the "macosx.c" file, take the others files as example
Go to /SDLFW/build/_premake4/ : Edit "premake4.lua" to make support MacOSX
Go to /SDLFW/build/macosx/ : Build SDLFW for MacOSX, don't forget to have the dependencies
Dependencies :
I simply directly save/open files in the %appdata%.minecraft\saves\<name>\computer\<id>\ folder.
I use Sublime Text 3: http://www.sublimetext.com/3
Here's a ComputerCraft package that provides syntax highlighting / auto-completion for all CC API functions: http://www.computercraft.info/forums2/index.php?/topic/10577-cc-syntax-highlightingcode-completions-v12-sublime-text-2/
I like best IntelliJ Idea with the Lua plugin. It's not exactly lightweight but has great code highlighting, autocompletion and lots of other highly useful features. Community edition is free.
A more lightweight recommendation would be Sublime Text 2. Especially I like the "code mini-map".
If you have some programming background, nothing really beats the book from the language designers, Programming in Lua. It's easy to find a PDF online. For novices, I'm not sure.
JavaScript has problems, but it's strictly better than PHP.
Some of the crap overlaps: There are type coercion problems in both, for instance. But as Crockford describes in JavaScript: The Good Parts, you can use a subset of JavaScript (enforced by a linter) that then makes the language behave in a predominantly sane manner.
Many of the coercion problems center around the == operator, for instance, but the === operator won't coerce. And this is well known among JavaScript users; not ignored, as you implied. No, it's not universal, but probably 90% of JavaScript users are junior developers who can't tell JavaScript from C++ OR PHP, so of course many wouldn't know...
More, though, JavaScript has many of the same advantages as Lua: JavaScript has had closures, first class functions, and prototypal inheritance from the start (both JavaScript and Lua gained inspiration from a language named self, if I remember correctly).
And PHP architecturally doesn't have the ability to write asynchronous code. So it can't scale the same way JavaScript can (HHVM does have some async ability, but it's not as complete, and it's not baked into 99% of the libraries and frameworks like it is in Node and JavaScript).
With ES6 fixing many of the remaining problems (when using the newer language features -- let and const instead of var, for-of instead of for-in, etc.), and TypeScript supporting all of the ES6 features today via transpilation, in addition to full optional type signatures?
No, it doesn't suck to be here any more. It's actually quite an awesome toolchain. The JavaScript world is different than when you looked last.
If you have never programmed before I strongly reccomend that you choose another book to learn about computer programming.
I recommend that you begin by reading "Think Java, 2nd edition". In my opinion Think Java is a good introductory book to programming.
Another supposedly good introductory book is Programming: Principles and Practice Using C++. However I can't comment much on it since I haven't read it myself.
> Book recommendation for professional developer
Programming In Lua, by the author of the language, is exactly that book. In fact, it's one of the better programming books ever written, which is all the more impressive because English is not Roberto's native language, but PIL has the succinct lucidity of K&R.