Jump to content

Will KSP 2 have better file/data formats?


kfsone

Recommended Posts

1 minute ago, Incarnation of Chaos said:

XML stored in a SQL database defined by a public XML schema. 

Ignore the DB, the question was file/data format.

2 minutes ago, DStaal said:

XML manages to combine the readability of binary with the performance of text.

No.

Please explain further.

Link to comment
Share on other sites

1 hour ago, shdwlrd said:

From a non programmer perspective, XML sucks to look at and is difficult to edit without the proper software. Plain text is the easiest to deal with.

I agree.

But from a programmer perspective plain text is a pain that has to be parsed and inserted into a DB structure to be handled anyway.

 

Edited by Curveball Anders
Link to comment
Share on other sites

1 hour ago, Curveball Anders said:

I agree.

But from a programmer perspective plain text is a pain that has to be parsed and inserted into a DB structure to be handled anyway.

XML doesn't help with that - it's actually one of the most complex plain text structures to parse correctly.  (Doing a full parse in theory can require multiple network connections...)  Working with just a subset helps that of course, but something like JSON which maps directly to an object structure is still typically much easier to parse and handle.

On the other hand, it's one of the more verbose plain text structures, and one where whitespace matters in some places but not in others, so it's complex and hard to read by a human.  The right tools can help work with that - but those tools aren't a text editor either, they're dedicated XML processing tools, so you're out of the 'just open it in NotePad' group as well.

There are situations where XML shines - but they typically involve multiple different processing programs running under different OS systems on complex data that doesn't map directly to any particular program's data structures.  Config files or save files for a desktop app is not it's best use, by a long shot.

Link to comment
Share on other sites

2 hours ago, Incarnation of Chaos said:

XML stored in a SQL database defined by a public XML schema. 

EBIDIC Base64 encoded with LHA compression, pgp signed and packaged for SOAP exchange over UUCP with FidoNet headers.

 

2 hours ago, DStaal said:

XML manages to combine the readability of binary with the performance of text.

Text that has been English->French->German->English translated, maybe.

Again, if you're going to go with text, at least make it programmatic like Lua or Python.

# Py
altitudes = {
 Planets.Kerbin: (60000, 70000, 60000),
 Planets.Gilly: (6000, 7000, 6000),
 Planets.Eve: (85000, 91000, 88000),
 # ...
}
RESOURCE = 'ore'
for planet, (lowest, highest, best) in altitudes:
  register_abundance(RESOURCE, lowest, highest, best)
-- Lua
scan_altitudes = {
 [ksp.Planets.Kerbin] = {60000, 70000, 60000},
 [ksp.Planets.Gilly] = {6000, 7000, 6000},
 [ksp.Planets.Eve] = {85000, 91000, 88000},
 -- ...
}
RESOURCE = "ore"

for planet, alts in pairs(scan_altitudes) do
  register_abundance(RESOURCE, table.unpack(alts))
end

Then imagine each of the above tables fleshed out for all the resources scansat handles.

Right now all of that is unpacked *into* the cfg file itself rather than only exposing to kerbal the parts that are actually important.

Python: I have a hate/kick-in-the-balls relationship with Python, but it helps pay my bills. CPython and Jython are slow, Pypy is JITed and faster but lacks the breadth of packages that makes cpython so popular.
Lua: Super-lightweight C bindings make it lightning fast, although like any language there are ways you can make it cripplingly slow (why are you creating a table of 5000 elements every iteration of a 10,000 iteration loop?), it's popular among modding communities and easy to embed, but the inventor was Portuguese so as a language it's about what you'd expect... if ... then .. end; while .. do .. end .. etc.

<not-seriously> Or we could roll back time and use uLPC/Pike! https://pike.lysator.liu.se/ </not-seriously>

 

Link to comment
Share on other sites

4 hours ago, Curveball Anders said:

... XML performance ...

No.

Please explain further.

One important factor of parsing is text volume - byte count. XML was designed as - its in the name - a Markup Language, and this manifests in the sheer amount of repetition and bloat present in XML documents.

json:
{"data": {"hello": {"world"}}}

XML:
<?xml version="1.0" language="en" encoding="utf-8">
<!DOCTYPE data SYSTEM "data.dtd">
<data>
 <key name="hello">
  <string>world</string>
 </key>
</data>
(plus add the dtd definition)

Terse XML:
<data><key name="hello"><string>world</string></key></data>

KSP CFG:
data
{
  hello = world
}

Or:
data { hello = world }

Lets review:

{"data":{"hello": {"world"}}}
<data><key name="hello"><string>world</string></key></data>
data { hello = world }

XML parsing generally tends to be either loose-and-slow or restrictive-and-slightly-less-slow. One of the big overheads of XML processing, especially for modern CPU architectures, is the unpredictable ordering of nodes coupled with the expectation of structure and the need to match tokens to a dynamic stack of them. You don't get this with json because there are no identifiers; in language parsing, you don't care at *parsing* what the identifiers are, it's an identifier or not. But in XML you care about matching </key> vs </data> at the right point.

(Obviously, you *could* do it differently, but is generally how the parsers that people use operate, whether they are sax- or dom-like)

The height of XMLs popularity coincided with a surge in Java development that emphasized XML, and the performance overhead of XML was generally amortized by assorted factors (jvm implementation/overheads, prevalent design patterns, what people were interoping with) so that things like SOAP didn't seem hideously bloated and obnoxious if you were working from inside Eclipse or JetBrains products.

Microsoft picked it up in C# as it also caught on in the C++ world, where it encountered bare-metal performance observations which was its undoing. Either I can parse the document agonizingly slowly and have it presented as an AST, or I can write a cache-antagonistic event model that can deliver me nodes blazingly fast but require me to implement an fsm for almost every document I want to work with, which turns out to be a super incredibly slow way to consume configuration files, message packets, etc when you are measuring performance in cpu cycles not milliseconds.

 

edit: indeed, the beauty of json is that it is [mostly] meaningful, or close to, in several languages, such that you can reuse the language's own parser to interpret it, increasing cache coherency.

Edited by kfsone
Link to comment
Share on other sites

11 minutes ago, kfsone said:

One important factor of parsing is text volume - byte count. XML was designed as - its in the name - a Markup Language, and this manifests in the sheer amount of repetition and bloat present in XML documents.


json:
{"data": {"hello": {"world"}}}

XML:
<?xml version="1.0" language="en" encoding="utf-8">
<!DOCTYPE data SYSTEM "data.dtd">
<data>
 <key name="hello">
  <string>world</string>
 </key>
</data>
(plus add the dtd definition)

Terse XML:
<data><key name="hello"><string>world</string></key></data>

KSP CFG:
data
{
  hello = world
}

Or:
data { hello = world }

Lets review:

{"data":{"hello": {"world"}}}
<data><key name="hello"><string>world</string></key></data>
data { hello = world }

XML parsing generally tends to be either loose-and-slow or restrictive-and-slightly-less-slow. One of the big overheads of XML processing, especially for modern CPU architectures, is the unpredictable ordering of nodes coupled with the expectation of structure and the need to match tokens to a dynamic stack of them. You don't get this with json because there are no identifiers; in language parsing, you don't care at *parsing* what the identifiers are, it's an identifier or not. But in XML you care about matching </key> vs </data> at the right point.

(Obviously, you *could* do it differently, but is generally how the parsers that people use operate, whether they are sax- or dom-like)

The height of XMLs popularity coincided with a surge in Java development that emphasized XML, and the performance overhead of XML was generally amortized by assorted factors (jvm implementation/overheads, prevalent design patterns, what people were interoping with) so that things like SOAP didn't seem hideously bloated and obnoxious if you were working from inside Eclipse or JetBrains products.

Microsoft picked it up in C# as it also caught on in the C++ world, where it encountered bare-metal performance observations which was its undoing. Either I can parse the document agonizingly slowly and have it presented as an AST, or I can write a cache-antagonistic event model that can deliver me nodes blazingly fast but require me to implement an fsm for almost every document I want to work with, which turns out to be a super incredibly slow way to consume configuration files, message packets, etc when you are measuring performance in cpu cycles not milliseconds.

 

edit: indeed, the beauty of json is that it is [mostly] meaningful, or close to, in several languages, such that you can reuse the language's own parser to interpret it, increasing cache coherency.

But you miss the beauty of XML.

It is a general markup language which means that it's not locked into any software solution.

Regardless of architecture, platform or language.

 

Link to comment
Share on other sites

4 minutes ago, Curveball Anders said:

But you miss the beauty of XML.

It is a general markup language which means that it's not locked into any software solution.

Regardless of architecture, platform or language.

Same can be said for several other markup languages - which are easier to parse and read.

In practice, as a general markup language XML is equally bad regardless of architecture, platform, or language.  Java is bad enough on it's own that it doesn't matter.  ;)  But paired with anything else, XML sticks out like a sore thumb - it's to general for efficiency, and to verbose to easy reading.  I've mentioned JSON as a better choice - you wouldn't want to encode Bills of Lading or a screenplay in JSON, but it's fully capable of what's needed here, and it's far easier to work with.

Link to comment
Share on other sites

7 hours ago, Curveball Anders said:

But you miss the beauty of XML.

It is a general markup language which means that it's not locked into any software solution.

No, but most people use the same backend libraries and when they don't the obscure one they pull out of the internet's nether or write themselves has a nice api and parses sample documents beautifully, and performs atrociously in real-world scenarios.

Parsing a balanced, arbitrarily tokenized tree out of a text document is just very costly on modern architecture. Cf CMake: Used to require balancing conditionals `if (thing) ... endif (thing)` but relaxed to optional when shown how much slower it was than `if (thing) ... endif()`.

And someone pointed out earlier, you really need some kind of tool to work with it rationally. What's the point of a text format that requires a GUI tool? If you're going to require a manipulation tool, store the data in an application/exchange beneficial format.

I used to (94-04) swear by an XML-based server-side scripting language, RXML; built this site using RXML and XML/XSLT. I get the beauty of XML in the right context, but there are good reasons we are using CSS and not XSLT in today's web, despite the fact that for a long time you could do so much more with XSLT/XPath in browser than CSS, and because it was XML-based, it was vastly less buggy.

Bandwidth and performance being two of them.

When the Golang team designed their language, parsing speed was a big factor. You can *compile* a 13,000 line golang application to an executable in the same time it takes gcc or clang to parse a 13,000 line file that contains "#include <cstdint.h>" + "\n"*13000, or the same time it takes msvc's cl.exe to start, or the same time it takes python on the same machine to invoke the same, empty function, 1,300,000 times -- i.e. milliseconds

Quote

In [11]: def f():
    ...:     pass
    ...:

In [12]: def g():
    ...:     for i in range(1300000):
    ...:         f()
    ...:

In [13]: %timeit g()
120.3 ms ± 2.33 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

(it's not that python is slow, it's that calling a function in cpython has a massive overhead)

[C:\Users\oliver\go\src\github.com\stretchr\testify]
> dir -r *.go | cat | measure -line | select -property Lines
   Lines
--------
   16822
[C:\Users\oliver\go\src\github.com\stretchr\testify]
> go clean ; Measure-Command { go build . } | select -property TotalMilliseconds
TotalMilliseconds
-----------------
          124.992

 

Edited by kfsone
Link to comment
Share on other sites

17 minutes ago, kfsone said:

No, but most people use the same backend libraries and when they don't the obscure one they pull out of the internet's nether or write themselves has a nice api and parses sample documents beautifully, and performs atrociously in real-world scenarios.

Parsing a balanced, arbitrarily tokenized tree out of a text document is just very costly on modern architecture. Cf CMake: Used to require balancing conditionals `if (thing) ... endif (thing)` but relaxed to optional when shown how much slower it was than `if (thing) ... endif()`.

And someone pointed out earlier, you really need some kind of tool to work with it rationally. What's the point of a text format that requires a GUI tool? If you're going to require a manipulation tool, store the data in an application/exchange beneficial format.

I used to (94-04) swear by an XML-based server-side scripting language, RXML; built this site using RXML and XML/XSLT. I get the beauty of XML in the right context, but there are good reasons we are using CSS and not XSLT in today's web, despite the fact that for a long time you could do so much more with XSLT/XPath in browser than CSS, and because it was XML-based, it was vastly less buggy.

Bandwidth and performance being two of them.

When the Golang team designed their language, parsing speed was a big factor. You can *compile* a 13,000 line golang application to an executable in the same time it takes gcc or clang to parse a 13,000 line file that contains "#include <cstdint.h>" + "\n"*13000, or the same time it takes msvc's cl.exe to start, or the same time it takes python on the same machine to invoke the same, empty function, 1,300,000 times -- i.e. milliseconds

(it's not that python is slow, it's that calling a function in cpython has a massive overhead)


[C:\Users\oliver\go\src\github.com\stretchr\testify]
> dir -r *.go | cat | measure -line | select -property Lines
   Lines
--------
   16822
[C:\Users\oliver\go\src\github.com\stretchr\testify]
> go clean ; Measure-Command { go build . } | select -property TotalMilliseconds
TotalMilliseconds
-----------------
          124.992

 

Please in laymans terms, can you explain what you're trying to demonstrate between the different encoding functions, and the different results.

(Non programmer here, I know you're timing compiling runs, but I don't know what you're trying to show with the results.)

Link to comment
Share on other sites

21 hours ago, kfsone said:

EBIDIC Base64 encoded with LHA compression, pgp signed and packaged for SOAP exchange over UUCP with FidoNet headers

 

 

Alright you got me here; i actually haven't heard of any of these.

On 3/17/2020 at 9:20 AM, Curveball Anders said:

Ignore the DB, the question was file/data format.

I'm aware; i was just surprised at most of the strong reactions to some of this stuff and wanted to get some cheeky laughs.

But even XML would be a massive improvement over what KSP implements now, but they have teased a scripting language based on Lua in KSP2 that may be a replacement for Module Manager. So anything for file/data formats would have to be compatible, and i'm not that familar with .Lua to know that.

Link to comment
Share on other sites

13 minutes ago, Incarnation of Chaos said:

Alright you got me here; i actually haven't heard of any of these.

I'm aware; i was just surprised at most of the strong reactions to some of this stuff and wanted to get some cheeky laughs.

But even XML would be a massive improvement over what KSP implements now, but they have teased a scripting language based on Lua in KSP2 that may be a replacement for Module Manager. So anything for file/data formats would have to be compatible, and i'm not that familar with .Lua to know that.

I've actually worked with all of those...

As for XML being an improvement over what KSP implements now - I don't see it.  What's used now is fairly close to JSON/YAML, and works pretty well.  An actual standard format would be a great help in that editors could help catch typos and structural problems, but otherwise the .cfg files and similar are pretty good in general.  I do see the points about numbers of files needing to be opened - but XML wouldn't help that in any way.  (And might actually hurt it.)

LUA would be a separate thing, in that it's a replacement language for some of the smaller code-based mods, allowing them to ship in text format.  (And therefore not need to be recompiled with every version of KSP.)  It's not really something to replace the current .cfg files, or even the persistence or craft files.

Link to comment
Share on other sites

4 minutes ago, DStaal said:

I've actually worked with all of those...

As for XML being an improvement over what KSP implements now - I don't see it.  What's used now is fairly close to JSON/YAML, and works pretty well.  An actual standard format would be a great help in that editors could help catch typos and structural problems, but otherwise the .cfg files and similar are pretty good in general.  I do see the points about numbers of files needing to be opened - but XML wouldn't help that in any way.  (And might actually hurt it.)

LUA would be a separate thing, in that it's a replacement language for some of the smaller code-based mods, allowing them to ship in text format.  (And therefore not need to be recompiled with every version of KSP.)  It's not really something to replace the current .cfg files, or even the persistence or craft files.

I didn't know if Lua would be able to access these things and make edits, so that's most of the source of my confusion. I'm aware of it being a scripting language, but that's about it...

And being able to pull a KSP .cfg file into notepad++ and use XML highlighting would be awesome, but i do understand that's not really a huge benefit. One of the biggest issues is just documentation; it's very difficult to actually figure out what in a .cfg file does what. And makes anything but very simple edits much harder than they should be; which is why i'm all for a more standard format be it XML or not.

But most of that should come with KSP2 being built from the ground up with a skilled team knowing what the ultimate product should look like/be capable of, so i'm not too worried.

Link to comment
Share on other sites

17 hours ago, shdwlrd said:

Please in laymans terms, can you explain what you're trying to demonstrate between the different encoding functions, and the different results.

(Non programmer here, I know you're timing compiling runs, but I don't know what you're trying to show with the results.)

Sure - golang turned 130,000 lines+ of program code into an executable program in just over 1/8th of a second. Because the C++ language doesn't give a hoot how difficult it is to write a parser for, it's obnoxiously slow. The cutting edge compilers for C++ are amazing, but given a file with one line of code and 130,000 empty lines, they take as long to do the first half of their job as golang took to read all the code, deal with all the external stuff, and spit out a runnable program.

In both cases, each line of code probably invokes tens or hundreds of functions. So, I demonstrated how long it'd take *just* to call that many functions. Calling a function is one of the most expensive operations in Python, so unless you can compile your 130k line program with a single function, Python wouldn't be able to do it. If you designed your language with that in mind, you could probably just about pull it off.

Python itself is a program that parses python source codes and then does Python stuff. But that program is written in something else, usually C. If we time how long Python takes to load an 130,000 line program, we can see how efficient the C-based python-parser is at parsing python:

[G:\tmp]
>
python -c "open('130k.py', 'w').write('a = False if True else False\n' * 130000)"
[G:\tmp]
>
measure-command { python .\130k.py } | select TotalMilliseconds

TotalMilliseconds
-----------------
1166.6474

(To be fair: this was a typical result, one of the 100 times it only took 144ms)

I've given Python an advantage here, too: the Go program was 130,000 lines of non-trivial code plus all the external stuff it references. Here, Python just had to process the same line 130,000 times over, huge advantage on modern hardware. And still ~10x slower than the go parser at parsing go.

 

The lion's share of that speed comes from the design of the language heavily factoring the cost of those decisions on parsing the language on modern hardware.

I'm expecting people to take certain things for granted here, so I acknowledge that I'm not providing end-to-end concrete proof that all other possibilities aren't in play. If you're actually interested, there's plenty of good stuff on language design and parsing out there :)

Was this what you were asking or were you referring back earlier to my example of XML vs CFG vs JSON?

5 hours ago, Curveball Anders said:

Might be a difference in perspective but I've coding for 40+ years and has learned (the hard way) that libraries change, goes obsolete or just plain stops working ;)

It's simply a fact that when most people parse XML they are using one of the core xml libraries - sax, libxml2, tinyxml, etree, ... The only good way to parse XML on modern hardware is to use a trivial schema and generate a schema-specific FSM statically or at runtime. At which point, you might better use something easier to parse in the first place. As a result, XML parsing has only gotten slower (relative to overall perf) over the decades, and I don't think I've seen any major developments in XML parsing since xml2 or etree.

5 hours ago, DStaal said:

LUA would be a separate thing, in that it's a replacement language for some of the smaller code-based mods, allowing them to ship in text format.  (And therefore not need to be recompiled with every version of KSP.)  It's not really something to replace the current .cfg files, or even the persistence or craft files.

It's not the worst. I really enjoyed embedding it into one project, I wrote a couple of fun WoW mods, but some stuff that seems like it should be easy takes a lot more effort; which is fair enough, it was originally intended as a config language with some programmability. I've found designers and artists can manage their way around it reasonably efficiently. I think the preference for words over symbols for flow (`if .. then ... end`, vs `if (...) { ... }`) makes it seem less alien to them.

5 hours ago, Incarnation of Chaos said:

I didn't know if Lua would be able to access these things and make edits, so that's most of the source of my confusion. I'm aware of it being a scripting language, but that's about it...

And being able to pull a KSP .cfg file into notepad++ and use XML highlighting would be awesome, but i do understand that's not really a huge benefit. One of the biggest issues is just documentation; it's very difficult to actually figure out what in a .cfg file does what. And makes anything but very simple edits much harder than they should be; which is why i'm all for a more standard format be it XML or not.

But most of that should come with KSP2 being built from the ground up with a skilled team knowing what the ultimate product should look like/be capable of, so i'm not too worried.

You can expose all the innards of your application automatically through most scripting languages, Lua included, but that's generally a bad idea because that requires a hell of a lot more exposure to internal documentation.

So instead - as with any language - you would probably want to present a relatively clean and lightweight set of interfaces. So, for example, you might have a "planet" module that exposes planet stuff, and encourage people not to write "if planet == 'Eeloo'" but "if planet == planets.Eeloo". That avoids localization issues, etc. Take a squint at the WoW Lua documentation.

Because we have C# for the actual mods in KSP, I don't know that an all-out Lua implementation would be the right thing; you probably still want people to write their mods in C#/C/C++ if possible, its just the configurations that you want to give flexibility to, and giving them the ability to be programmatic would be a huge boon.

Link to comment
Share on other sites

5 minutes ago, kfsone said:

 

You can expose all the innards of your application automatically through most scripting languages, Lua included, but that's generally a bad idea because that requires a hell of a lot more exposure to internal documentation.

So instead - as with any language - you would probably want to present a relatively clean and lightweight set of interfaces. So, for example, you might have a "planet" module that exposes planet stuff, and encourage people not to write "if planet == 'Eeloo'" but "if planet == planets.Eeloo". That avoids localization issues, etc. Take a squint at the WoW Lua documentation.

Because we have C# for the actual mods in KSP, I don't know that an all-out Lua implementation would be the right thing; you probably still want people to write their mods in C#/C/C++ if possible, its just the configurations that you want to give flexibility to, and giving them the ability to be programmatic would be a huge boon.

Yeah; they're intending it as a Module Manager replacement. Anything beyond that would be done by calling KSP2's modding API's that they've implemented; which as you said would be C# or C++ depending on the scope of the mod.

And that would be incredible honestly; I'd much rather deal with my configs being classes than seemingly random files. At least then i know exactly what trail to follow if whatever I'm trying to do isn't in that class; due to inheritance.

Didn't even think of localization because I'm a filthy English speaker, but you're correct that's going to make it 100 times easier. Instead of building everything from the ground up for a given language, you'd just have to replace all the calls to the EN localization module with calls to one of the desired language. The code itself wouldn't even care to know what language it was outputting (Rightfully, computers only know binary at the end of it all anyway)!

But yeah; i never thought they were going for a full .Lua implementation. They've always talked about it in the context of scripting; still excited to see what people do with it though. 

 

Link to comment
Share on other sites

1 minute ago, Incarnation of Chaos said:

Didn't even think of localization because I'm a filthy English speaker, but you're correct that's going to make it 100 times easier. Instead of building everything from the ground up for a given language, you'd just have to replace all the calls to the EN localization module with calls to one of the desired

 

English is my first language, but American is my second, and I love creating a file called "localization.h" and having it open a namespace called "localisation" and then spelling it with a 'z' in enums and an 's' in functions/classes :) 

Gotta have a pattern, or you're trolling yourself as well as your co-workers!

Link to comment
Share on other sites

4 minutes ago, kfsone said:

English is my first language, but American is my second, and I love creating a file called "localization.h" and having it open a namespace called "localisation" and then spelling it with a 'z' in enums and an 's' in functions/classes :) 

Gotta have a pattern, or you're trolling yourself as well as your co-workers!

That's actually pretty hilarious; if you ever make a game that'd be a fantastic Easter egg

Link to comment
Share on other sites

1 hour ago, kfsone said:

"if planet == 'Eeloo'" but "if planet == planets.Eeloo".

This has managed to hit a minor peeve of mine, that I try to push:

It should be "if planets.Eeloo == planet".  ;)  (If you typo this and only put in one equals sign, the code will fail at compile/parse.  If you typo the above the same way, you get a difficult-to-track-down bug...)

Link to comment
Share on other sites

14 minutes ago, DStaal said:

This has managed to hit a minor peeve of mine, that I try to push:

It should be "if planets.Eeloo == planet".  ;)  (If you typo this and only put in one equals sign, the code will fail at compile/parse.  If you typo the above the same way, you get a difficult-to-track-down bug...)

Care to explain? Both are asking the same question "Is a Class named Eeloo part of the Planet Class", so any differences would be down to order of operations. Also i didn't see either with any single "=" operators.

Link to comment
Share on other sites

38 minutes ago, DStaal said:

This has managed to hit a minor peeve of mine, that I try to push:

It should be "if planets.Eeloo == planet".  ;)  (If you typo this and only put in one equals sign, the code will fail at compile/parse.  If you typo the above the same way, you get a difficult-to-track-down bug...)

Only in more C-like languages, the majority of languages disallow assignment in a condition like that, often because they hated this when they were writing their language in C :)

In C++ `if (planets.Eeloo.operator==(planet))` could do something very different than `if (eeloo.operator==(planets.Eeloo))` for a host of reasons, especially since == is an operator and not guaranteed to be commutative. There's a lot better ways than reverting to yoda-conditionals. I make judicious use of const, nullptr, enums and constexpr, and I generally hold myself to -Wall -Wextra -Wpedantic.

 

20 minutes ago, Incarnation of Chaos said:

Care to explain? Both are asking the same question "Is a Class named Eeloo part of the Planet Class", so any differences would be down to order of operations. Also i didn't see either with any single "=" operators.

C's definition of the if, while, etc conditionals is in terms of `expression`, and `expression` is any statement that resolve to a value (I'm going to avoid C++'s rvalue mayhem and stick to C).

Thus `int x = 0, y = 2; if (x = y) { printf("Hello, %d\n", x); }` will print Hello, 2 (https://ideone.com/Lr3qR0)

Why?

Because the '=' operator evaluates to the value assigned, so you can do `x = y = z = a = b = c` (b = c; a = (b = c); z = (a = (b = c)); ...` which sets the value of c to all the variables. So `if (x = y)` assigns y to x, then evaluates the value it assigned, which was non-zero, so true.

 

[edit: using -Wpedantic: http://coliru.stacked-crooked.com/a/47e2e78a3ca22333]

Edited by kfsone
Link to comment
Share on other sites

9 minutes ago, Incarnation of Chaos said:

Care to explain? Both are asking the same question "Is a Class named Eeloo part of the Planet Class", so any differences would be down to order of operations. Also i didn't see either with any single "=" operators.

In nearly all computer languages '==' means 'compare to see if they are equal' while '=' means 'assign the value on the right to the variable on the left'.  Also, in many computer languages an assignment in a conditional is allowed - but will succeed in all cases if it's allowed.  (Not as many as the above, admittedly.)

The question I see the statement saying is 'if the planet in question is the planet Eeloo', or 'if the planet Eeloo is the planet in question'.  So they could be different, but we're checking if they're the same.  However 'planet = planets.Eeloo' means 'planet is now planet Eeloo'.

So 'if planet == planets.Eeloo' succeeds if the two values are the same.  'if planet = planets.Eeloo' succeeds *always* if the language allows assignment in the if statement, and changes the value you were comparing as well.  'if planets.Eeloo = planet' fails even if the language allows assignment, as long as 'planets.Eeloo' isn't a variable.

(And yes I'm aware that if they're both more complex objects this could be more complex yet - I'm assuming that 'planets.Eeloo' is a simple string or binary constant.)

So in these three cases:

Case1:

planet = planet.Dres;
if planet == planet.Eeloo {
  print true;
}

Case2:

planet = planet.Dres;
if planet = planet.Eeloo {
  print true;
}

Case3:

planet = planet.Dres;
if planet.Eeloo = planet {
  print true;
}

In case 1, at the end nothing is printed, and 'planet' is Dres.  In case 2, at the end 'true' is printed and 'planet' is Eeloo.  Case 3 won't compile, and therefore doesn't run, with a compiler message saying it failed at the if statement.

Generally it's easier to debug an issue when the compiler can point it out to you than when you have to dig for it.  ;) 

Link to comment
Share on other sites

2 minutes ago, DStaal said:

In nearly all computer languages '==' means 'compare to see if they are equal' while '=' means 'assign the value on the right to the variable on the left'.  Also, in many computer languages an assignment in a conditional is allowed - but will succeed in all cases if it's allowed.  (Not as many as the above, admittedly.)

The question I see the statement saying is 'if the planet in question is the planet Eeloo', or 'if the planet Eeloo is the planet in question'.  So they could be different, but we're checking if they're the same.  However 'planet = planets.Eeloo' means 'planet is now planet Eeloo'.

So 'if planet == planets.Eeloo' succeeds if the two values are the same.  'if planet = planets.Eeloo' succeeds *always* if the language allows assignment in the if statement, and changes the value you were comparing as well.  'if planets.Eeloo = planet' fails even if the language allows assignment, as long as 'planets.Eeloo' isn't a variable.

(And yes I'm aware that if they're both more complex objects this could be more complex yet - I'm assuming that 'planets.Eeloo' is a simple string or binary constant.)

So in these three cases:

Case1:


planet = planet.Dres;
if planet == planet.Eeloo {
  print true;
}

Case2:


planet = planet.Dres;
if planet = planet.Eeloo {
  print true;
}

Case3:


planet = planet.Dres;
if planet.Eeloo = planet {
  print true;
}

In case 1, at the end nothing is printed, and 'planet' is Dres.  In case 2, at the end 'true' is printed and 'planet' is Eeloo.  Case 3 won't compile, and therefore doesn't run, with a compiler message saying it failed at the if statement.

Generally it's easier to debug an issue when the compiler can point it out to you than when you have to dig for it.  ;) 

Where did he use "=" instead of "=="?

I know "=" assigns a value to a variable, and "==" compares two variables. iv'e been writing conditional statements and loops most of the evening actually, so i guess my brain may be a bit fried and i'm not seeing something right in front of me.

 

Link to comment
Share on other sites

16 minutes ago, DStaal said:

In nearly all computer languages '==' means 'compare to see if they are equal' while '=' means 'assign the value on the right to the variable on the left'.  Also, in many computer languages an assignment in a conditional is allowed - but will succeed in all cases if it's allowed.  (Not as many as the above, admittedly.)

Only C-like languages, the majority actually use '=' in both cases or give them distinctive behaviors (void operator=, bool operator==)

Lua 5.2.4 Copyright (C) 1994-2015 Lua.org, PUC-Rio
> x = 1
> y = 2
> if x = y then print("hello", x) end
stdin:1: 'then' expected near '='
> if x == y then print("hello", x) end
>
Python 2.7.17 (default, Nov 7 2019, 10:07:09)
[GCC 9.2.1 20191008] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> x, y = 0, 2
>>> if x = y: print("Hello", x)
File "<stdin>", line 1
if x = y: print("Hello", x)
^
SyntaxError: invalid syntax
oliver@dogfish:~$ perl
x = 0; y = 2; if (x = y) { print("Hello", x) }
Can't modify constant item in scalar assignment at - line 1, near "0;"
Transliteration replacement not terminated at - line 1.
oliver@dogfish:~$ rustc test.rs -o test.exe
error[E0308]: mismatched types
--> test.rs:4:8
|
4
| if x = y {
| ^^^^^
| |
| expected bool, found ()
| help: try comparing for equality: `x == y`
|
= note: expected type `bool`
found type `
()`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
oliver@dogfish:~$ go run test.go
# command-line-arguments
./test.go:7:14: syntax error: assignment x = y used as value

But head C-ward

oliver@dogfish:~$ node
> x = 0; y = 2;

2
> if (x = y) { console.writeln("Hello", x); }
TypeError: console.writeln is not a function
> if (x = y) { console.write("Hello", x); }
TypeError: console.write is not a function
> if (x = y) { console.log("Hello", x); }
Hello 2

undefined

But even C-derivatives have moved away from this behavior because it's bad:

oliver@dogfish:~$ tail +9 test.cs
   if (x = y) {
     Console.WriteLine("Hello");
   }
 }
}

oliver@dogfish:~$ mono-csc test.cs
test.cs(9,7): error CS0029: Cannot implicitly convert type `int' to `bool'
Compilation failed: 1 error(s), 0 warnings

16 minutes ago, DStaal said:

So 'if planet == planets.Eeloo' succeeds if the two values are the same.  'if planet = planets.Eeloo' succeeds *always* if the language allows assignment in the if statement, and changes the value you were comparing as well.  'if planets.Eeloo = planet' fails even if the language allows assignment, as long as 'planets.Eeloo' isn't a variable.

That depends on what planets.Eeloo is. It could be an enum, it could be a constant of value 0.

If Eeloo *is* an object, you could also easily determine whether you really ever want people assigning planets to each other and simply disable it, require an rvalue, etc.

Edited by kfsone
Link to comment
Share on other sites

×
×
  • Create New...