This is absolutely amazing for debugging purposes. Also you never have to worry about corrupt save files or anything of it's ilk. Development is easier, diagnosing problems is easier, and using a programmatic data structure on the backend means that you can pretty much keep things clean and forward compatible with ease.
(Oh, also being able to debug by altering the save file in any way you want is a godsend).
Is there any way that arbitrary code in the file could compromise the user's system? If so, does the user know to treat these data files as executables? Is there any way someone untrusted could ever edit the file without the user's knowledge? Even in combination with other programs the user might be running? Are you sure about all of that?
Maybe Lua in particular is sandboxed so that's not a problem (beats me), but in general this is an area where safe high-level languages can all of a sudden turn dangerous. Personally I would rarely find it worth it.
I apologise in advance for ranting... I hope this is not too off-topic, but instead a "zoom out" on the issue.
This touches on something deep and wrong about how we use computers these days. Computers are really good at being computers, and the amplification of intellectual capabilities they afford is tremendous, but this is reserved for a limited few that were persistent enough and learned enough to rediscover the raw computer buried underneath, and what it can do.
For example, I dream of a world where everything communicates through s-expressions, all code is data and all data is code. Everything understandable all the way down. Imagine what people from all fields could create with this level of plug-ability and inter-operability. We had a whiff of that with the web so far, but it could be so much more powerful, so much simpler, so much more elegant. All the computer science is there, it's just a social problem.
I understand the security issues, but surely limiting the potential of computers is not the solution. There has to be a better way.
In Loa 5.1 you can use setfenv http://www.lua.org/manual/5.1/manual.html#pdf-setfenv
And in Lua 5.2 the functions that eval strings receive the global scope as an optional parameter. http://www.lua.org/manual/5.2/manual.html#pdf-loadfile
1. http://stackoverflow.com/questions/1224708/how-can-i-create-...
2. http://stackoverflow.com/questions/4134114/capabilities-for-...
I find it easier to trust Lua than similar facilities in other programming languages because the kernel of the language has a relatively simple semantics, so the TCB of a sandbox is lower, and the source is easier to understand than most other languages.
Note that sandboxing in Lua 5.2 has a still simpler semantics than for Lua 5.1 - few other languages evolve in a way that makes the language easier to trust.
But it's still code, so you can e.g. inject an infinite loop and the loader will hang. (You can protect against this, you can install a debug hook that gets called after every N instructions executed, and kill the loader.)
The biggest 'concern' would be save hacking, but at the end of the day that will happen no matter what so it doesn't bother me much.
I leaned heavily on Python's pickle module for serializing a few thousand entities to disk a few years ago. By streaming them to the application at startup time, it remained plenty fast for all datasets it'd encounter. I intended to replace it with SQLite one day, but I never had to. I could just keep them all in memory.
I'd probably choose something a bit safer now, but it was hard to beat the simplicity.
Edit: Igglyboo has a point too.
Also, the Tiled Map Editor exports directly to Lua.
local t = {}
t = {["foo"] = "bar", [123] = 456}
t.foo2 = "bar2"If you ever used maven xml configs, java object marshalling or c# xml you would understand the pains of using xml as a file format for software projects and data representation. You have to find a solution that is language agnostic, neither LUA or JSON is.
Could persist to disk as a binary, sql or a plist (xml).
I guess the only downside is, that if you got a lot of composite classes all with their own properties and associations (say a graph), there's a lot of manual work to be done.
Thanks for sharing this, it's one of those ideas that (to me) seems so brilliant in its simplicity that I probably would've never thought of it.
Any hiccups in the day-to-day work using this approach? I'm just trying to get a better idea of the workflow since I'm very seriously considering applying it to my next project.
I’ve created mods of the game where you fun faster but gravity is stronger, and where all levels are randomly mixed into one level, and where the dangerous falling platforms also give you energy while you’re on them, and where the sound effects give the player clearer feedback on what they’re doing. And though I could cheat by multiplying my score by 1000 and submitting it online, I actually have been careful to always comment out the high-score saving and submission code in each of my mods.
I like the game much more than if the developers had obfuscated the Lua files so I couldn’t read and edit them.
The only argument against human-editable text files is parsing speed, not security.
If the player has fun, it's a nice feature! :D
Hell, I've used it myself more than a few times.
If not loading things is important to you, mind.
But if I want something that is able to express data structures customized by myself, usually with hierarchical data that can be verified for validity and syntax (XML Schemas or old-school DTD), what other options are there?
Doing hierarchical data in SQL is a bitch and if you want to transfer it, well good luck with a SQL dump. JSON and other lightweight markup languages fail the verification requirement.
If you really need a hierarchical serialization format that is "verified for validity and syntax", the problem is that XML has prevented the adoption of something better (because it was "good enough").
If you don't need that, then XML is overkill and bloat and makes your format less readable than it could be. And you rarely need it, because either your data is computer-generated and -read, so there's little point in putting in extra schema checks, or schema verification is woefully insufficient (because it can't verify the contents of fields, relations between fields, or a ton of other stuff that can accidentally go wrong).
> But if I want something that is able to express data structures customized by myself, usually with hierarchical data that can be verified for validity and syntax (XML Schemas or old-school DTD), what other options are there?
What would be better?
Is XML schema really so much better than e.g. JSON schema?
To me it feels like there's an impedance mismatch between the kind of structures XML lends itself to and the kind of structures programs are good at dealing with. So for program-to-program communications with a certain level of validation I find Protocol Buffers is a much better fit. Conversely in cases where human readability is really important, XML isn't good enough compared to JSON.
Namespaces exist to solve a real-world problem that happens in real-world use cases (SVG embedded in HTML, HTML embedded in RSS). While it would be nice to look at things that are complex and say "it would be less complex for these trivial cases without this feature", in reality there are then common use cases that become more complex or even impossible in the general case, which seems like a very short-sighted benefit. Namespace prefixes are really not that difficult to configure, and once configured XPath makes them very easy to use :/.
And because of this almost no-one bothers to actually handle it properly so you often can't actually use the advanced features even if you wanted to.
{ "name": "bob", "salary": 1e999 }
Ah crap! Deserializer blew (in most cases silently converting the number to null) <person>
<name>bob</name>
<salary>1e999</salary>
</person>
No problem. The consumer can throw that at their big decimal deserialiser.And the following is not acceptable as it breaks the semantics of JSON and requires a secondary deserialisation step as strings ain't numbers...
{ "name": "bob", "salary": "1e999" }
JSON is a popular format but it's awful.> doing everything in XML is a stupid idea (e.g. XSLT and Ant)
XSLT actually made a lot of sense. If everyone writes code to transform format1 to format2 then what you end up with a lot of slightly different transformations. Its main downfall, just like XML itself, was that it was annoying and time consuming to write.
How would you replace all this if you moved away from XML?
http://git.hohndel.org/?p=subsurface.git;a=tree;f=xslt;hb=HE...
And impossible to debug. Write once, do something else for some weeks, and trying to understand what you were doing at a later point is nearly impossible.
It remains annoying and time-consuming :) But there's no better option for reliably creating valid EPUBs to a predetermined business specification.
If we start out instead with something that's turing complete and simple to begin with (perhaps S-expressions?), we can (often trivially) write our own validators/type-checkers, or any other processing tool to verify the document structure, with few or no constraints, and without requiring the effort and expertise to parse complex syntax.
Simply put, XML does not correctly model the data by which we intend to interchange. It was a noble effort, but it didn't come from a place of innovation. It came from corporate needs for standardization.
<customer>
<account>
<type>Personal</type>
...
</account>
<account>
<type>Business</type>
...
</account>
<custid>496F3AB</custid>
</customer>
This may seem innocuous, but XML allows mixing of arrays and objects too liberally, and makes automatic parsing overly complex. At first <customer> appears to be an array of account objects, but wait now that we reach the end we find that <customer> is an object with multiple keys and must create an unnamed array key to hold accounts.XML is a document markup language, not a data format.
<customer custid="496F3AB">
<account>
<type>Personal</type>
...
</account>
<account>
<type>Business</type>
...
</account>
</customer>
it would make a lot more sense, I think.The likelihood of a JSON feature biting you in the ass like that is far lower. Don't use XML until you actually need something XML SPECIFICALLY provides.
Also JSON easily translates with easy to work with dictionaries and lists, XML parsers take more code to work with equivalent items.
S-expressions work great. Syntax checking is far simpler, and validity checking is hence something you can roll yourself (and writing an S-expression schema checker ain't tough).
Besides, since 1960 or thereabouts we have S-Expressions. The world should just have used that without reinventing the wheel once again.
Firstly some clarification - this appears to just be about the persistence format for his dive log. It was XML, now it's git based with plain text.
As someone who had to manage a system which worked with plain text files structured in a filesystem for a number of years in the 1990s, this is done to death already.
You now end up with the following problems: locking, synchronising filesystem state with the program, inode usage, file handles to manage galore and concurrency. All sorts.
Basically this is a "look I've discovered maildir and stuffed it in a git repo".
Not saying there is a better solution but this isn't a magic bullet. It's just a different set of pain.
Which is why he's reusing git for resolving those pain points? Well presumably all except "synchronizing filesystem state with the program" -- where he's gone from using some kind of xml parser to marshal xml to objects/structs in ram to using a (simple(r)?) text parser to do the same.
I'm guessing he just writes/reads a full (part) of a log (a branch of the full tree, or whatever is used in the program. Maybe a list anchored at a date?) -- and lets git sort the history/backup thing.
So, yes, it's a different format, but I think the argument you're making is off -- seeing as he already has git for that? It's more like combining Maildir (or mboxes, only commited when valid) and git.
There's not much more to infer from the comment.
Unless he's invented a new ASN.1 encoding which plugs into libgit or something or a new text serialisation format (both unlikely).
Git is so well-designed that expert users manage to trash their repositories and propagate the damage.
Maybe that's not a problem of libgit. But tools are both the infrastructure and the UI.
But what he replaces it with is a git object store. Each xml-node becomes a git object. They each point to a parent (just as git commits point to a parent commit).
Now writing to this datastore means adding a new node to the git object database and changing the parent references.
Where git stores commits that are related sequentially in time, this stores nodes in a tree relationship that IS the document.
If he's not talking about this then I'd like to officially take credit for my weird idea right now.
Regardless, I would think that some applications are simple enough (store few enough separate objects in the file system) that the issues you cite are not likely to cause a problem.
Running the new executable then loaded the new configuration. This worked like a champ, up until the Age of Antivirus Software, which always had much grief over writing to executable files.
It's a trick I learned from the original Fortran version of ADVENT.
You could write hex values in the program text editor, then you could tell the calculator to execute the hex codes as machine code. I understand the previous models, TI-82 and TI-85, were hacked / backdoored to run user-supplied assembly language, so TI responded by including an official entry point and developer documentation for the TI-83.
People later wrote loaders which allowed programs to be stored as binary instead of text (using half the space). Some loaders also had the capability to run binary programs by swapping them into the target address rather than copying them (theoretically a third option would be possible, running programs in-place if they weren't written to depend on their load address, but this wasn't a direction the community went in. gcc users may be familiar with -fPIC which produces code which can run from any address, and this flag is necessary when compiling code for shared libraries.)
This allowed people to create massive 20K+ applications (an RPG called Joltima comes to mind), that used most of the available RAM.
The fact that this loading scheme made static variables permanent was also quite convenient. (And most variables were static; stack-based addressing would be tough because the Z80 only has two index registers, one of which is used -- or perhaps I should say "utterly wasted" -- by the TI-83 OS.)
The next generation, the TI-83+, included I think 256K of flash ROM, and a special silver edition was released which contained 2 MB.
The other huge thing I learned from ADVENT was polymorphism. The comment in the source code "the troll is a modified dwarf" was an epiphany for me.
"XML is what you do to a sysadmin if waterboarding him would get you fired."
Made my day :-)
I am currently stuck on a project I want to start becasue I cannot get it to fit right in my (future) head. And I am glad I am not an idiot for not being able to knock out my next great project in between lattes.
(Ok, in direct comparison terms I am an idiot, but at least its not compounded)
"A change in perspective is worth 80 IQ points."
-- Alan Kay
My biggest hurdle solving new problems is divining a unifying, simplifying metaphor. Once you have the right notion, that Eureka! moment, everything falls into place, like magic.Like how Kepler was able to fully explain Bache's astronomical data once he realized the planets orbits the sun.
Personal example: I used to write print production software. Placing pages onto much larger sheets of paper that get folded and bound into a book. A task called image positioning aka imposition. It took me years to figure out how to model the problem. Key insight was simulating the work backwards, from binding back to the press. Then when I showed the new solution to my coworkers, the response was "Well, duh."
G+ is largely misunderstood. It is a lousy tool for interaction with people connected to you purely socially. It's a very good way to find and interact with people connected to you by interest.
Sure, XML can be nasty, but thats very much a function of the care taken to a) format the file sensibly b) use appropriate structure (i.e. be as specific as necessary, and no more).
Without it, publishing would be stuck in a morass of nebulous, ill-documented proprietary messes, and a great deal of current learning would be at risk of being lost to posterity. The fact that there are associated open standards such as XSLT with which to transform it is just the icing on the cake as far as publishing is concerned.
This is why there's so much distaste for XML - people try to use it for applications where it isn't ideal (and there are many more of those than there are applications where it is ideal) because they've swallowed someone else's hype, and as a consequence they have a bad time. If not for the unbelievable exaggeration a few years back (I heard people claim without irony that XML - a markup language for god's sake - would literally change the world), the divisiveness wouldn't exist, and it would be a technology used by experts quietly getting on with the jobs it's best for.
That's only true for minimally formatted documents. For anything that approaches professional typesetting requirements, XML is a nightmare.
By far the biggest problem, it the requirement that inner elements must be closed before outer ones can be. This frequently means that the software must do a huge amount of read-ahead to figure out which aspect of the formatting changes first to make that formatting element innermost.
Sometimes, that's simply not possible to arrange and so you have to close a whole bunch of elements and then reopen all but one of them.
All this because a constraint of the format.
Ideal formats, such as used by typesetting systems that don't use XML, allow you to say: keep this formatting trait on until it's switched off. There is no concept of every element needing to be a subset of its encompassing element.
I just hope that opinion of it as a markup language can be rehabilitated before someone reinvents it and kicks off a new hype cycle.
"+Aaron Traas no, XML isn't even good for document markup.
Use 'asciidoc' for document markup. Really. It's actually readable by humans, and easier to parse and way more flexible than XML.
XML is crap. Really. There are no excuses. XML is nasty to parse for humans, and it's a disaster to parse even for computers. There's just no reason for that horrible crap to exist.
As to JSON, it's certainly a better format than XML both for humans and computers, but it ends up sharing a lot of the same issues in the end: putting everything in one file is just not a good idea. There's a reason people end up using simple databases for a lot of things.
INI files are fine for simple config stuff. I still think that "git config" is a good implementation."
Subversion has a really good XML output for its log command which is a joy to use (and that's something to say if you work with XML) whereas with git you always have ugly format options that are most of the time underdocumented.
I just had a quick scan of the user guide. It's very impressive. Looks like markdown but with all the edge cases thought out.
At its core XML (if you ignore all the DTD, namespace and entity rubbish) is both simpler and more powerful than this. You have text, tags and attributes. What those tags and attributes mean is up to the application, but at the very least you can be sure that the document can always be reliably parsed into a form you can work with.
I'd really like to hear more about this perspective, if anyone feels like they can elaborate.
I'm sure quite a lot of people will easily recognize it. :^)
Subject: Re: S-exp vs XML, HTML, LaTeX (was: Why lisp is growing)
https://groups.google.com/forum/message/raw?msg=comp.lang.li...
1. There's very little detail here; it's a nicely worded, emotionally charged piece that leaves a lot of detail unaddressed, e.g. "'I would like to hear why you think it is so bad, can you be more specific please?' If you really need more information, search the Net, please." That's not very helpful.
2. It argues for 'simpler' markup via the removal of attributes. Where possible, I totally agree, as at least hinted at in my original post. Sometimes, though, this would be impossible or unwieldy (e.g. HREF attribute on an A element).
3. Character entities vs. unicode - totally agree. Wherever possible, I use proper unicode characters rather than ugly character entities in my markup.
4. "But the one thing I would change the most from a markup language ... is to go for a binary representation." Linus would vehemently disagree on this point.
I didn't really know what he was talking about but I think this is it.
The title does need changing though as it is definitely file formats under discussion not file systems.
But here we have threads about Lua, why people hate XML and love JSON and all kinds if irrelevant issues which have been well hashed elsewhere ad nauseam. Why not restrict to an analysis of whatever it is Linus developing?
HN is getting truly annoying and sucky, if it isn't so already.
This I like. The race away from the waterfall straw man has also stripped us of the advantages of BDUF.
While rigid phase-driven project management helps nobody, I think there's still room for speccing as much as we can upfront within iterative processes.
Or you could run to the IDE and start ramming design pattern boilerplate down its throat the second you're out of the first meeting ;)
A lot of people use AGILE to avoid planning at all, which is a particular destructive anti-pattern, and the exact opposite of what you need.
Yup, I've seen this a lot.
In one instance "Agile" meant I could finish a major task using an unfamiliar language, framework and code base in short order.
Genuinely, the customer was told "Of course, fuzzix here is familiar with Agile processes so you should have this in 3 weeks".
edit of course this also meant there was no formal spec for the task, though I did have a photo of the whiteboard.
I think that the first "how" should be planned as much as anything else. I understand how you refactor from v0.0.1 to v5.34.2 iteratively, but I think that getting from vNothing to v0.0.1 is qualitatively different.
If I don't have a complete idea of how my minimally functional thing will work that is small enough that I can completely hold it in my head, and instead just architect by agglutination and test writing, 1) my results are going to be hacky garbage, 2) my first 50 iterations are going to be devoted to replacing it all haphazardly to fix bugs, and 3) the code and interface will become increasingly more complex, harder to work with, and strewn with special cases.
When v0.0.1 is well planned, v2.5.2 may not look anything like the plan anymore, but in my experience it becomes shorter, cleaner, and more correct rather than a giant ball of band-aids propped up with tests.
This might be a tangential discussion. Earlier, I used to have a similar approach. Can't code until I have the complete picture. But, it's tough to do in a commercial world and you have deliverables. So, nowadays, I start with what I know and scramble my way until I get a better picture. There are times when that approach works. But, there have been days where I was like - "wish I had spent some more time thinking about this".
I am curious how folks on HN handle this "coding block".
A notebook: I'll write down some notes and just kind of free write whatever thoughts come to mind. If there's something that I think is important to come back to, I'll draw an empty box in the left margin (to be filled with a check mark later)
Readme: start writing the Readme for the project, even if you're not entirely sure of the details. Include code examples. If you don't like how the API is coming together, change it. It's way less work to modify the API now than it will be later.
Write a test: I don't always unit test, but when I do I test first :). This works well on projects that already have a decent test suite. It's kind of an executable version of the Readme.
Branch and Hack: branches are cheap. Make one and start playing. Don't like how it's turning out? Make a new branch and try again!
Ctrl-Z: maybe the answer won't come to you right away. Let it sit and run in the background for a while and come back to it. If I'm worried about forgetting details, I'll write it down in a notebook first.
(other than that I agree it's a good solution)
git as the basis of filesystem is interesting, hope we don't need to manually make branches and commits to use it
I'm not sure why git is the best tool for the job in this case, even after reading the post & some of the contents.