Let's say I have an interface called Squid.
interface Squid {
void DisplayInfo();
}
And we have a bunch of different types of squids:
class AquaticSquid inherits Squid {
void DisplayInfo() {}
void Swim() {}
}
class LandSquid inherits Squid {
void DisplayInfo() {}
void Crawl() {}
}
class BasicSquid inherits Squid {
void DisplayInfo() {}
void BasicAttack() {}
}
class AdvancedSquid inherits Squid {
void DisplayInfo() {}
void AdvancedAttack() {}
}
Here's everything a squid can be:
aquatic | land | |
---|---|---|
basic | basic-aquatic | basic-land |
advanced | advanced-aquatic | advanced-land |
How would I go about create an instance of a squid? Should I go about creating 4 classes BasicAquaticSquid
, BasicLandSquid
, AdvancedAquaticSquid
, AdvancedLandSquid
like this:
class BasicAquaticSquid inherits BasicSquid, AquaticSquid {
void DisplayInfo() {}
void Swim() {}
void BasicAttack() {}
}
BasicAquaticSquid squid;
squid.Swim();
I think that's called the Abstract Factory method? It seems very tedious though. Any better way of doing so?
Thanks
@DynamicSquid use the duplicate
macro in the duplicate
crate
// eek rust syntax highlighting
extern crate duplicate;
use duplicate::duplicate;
trait Squid {
fn display_info(&self);
fn new() -> Self;
}
#[duplicate(
typ atk mve;
[ AdvancedAquatic ] [ advanced_attack ] [ swim ];
[ BasicAquatic ] [ basic_attack ] [ swim ];
[ AdvancedLand ] [ advanced_attack ] [ crawl ];
[ BasicLand ] [ basic_attack ] [ crawl ];
)]
trait typ {
fn atk(&self);
fn mve(&self);
}
/* ... */
fn main() {}
(will invite you to said repl)
Stack Overflow link
@DynamicSquid also come on the NightLang pr #65
@firefish Why did I not think of that!? Rust duplicate crate, there we go, problem solved.
@firefish genius
@xxpertHacker I did spend some time combing through Stack Overflow, as you can tell by the link
@DynamicSquid @Lethdev2019
Slice, dusk, and night... what do you think?
(dusk is smaller because it ain't a language)
@firefish i like it but when are we gonna work on slice?
@Lethdev2019 I am, every day. Working on the SoN VM
i mean slice itself. @firefish
@Lethdev2019 Well how? We can start by making the interpreter, I mean all the sliec stuff is in the SoN VM proto.md, so check there
ok in it. @firefish
also - i am using linux now. @firefish
@Lethdev2019 Same, I like to use my dualboot, but I'm not using it atm because I want to do some dev now, not wait an hour to update it to Fedora 33
@Lethdev2019 It's this repl, you haven't come on
@Lethdev2019 Hi, come on the repl named "SoN-VM"
@firefish are you online?
@firefish I'm surprised that stuff on Rust can even be found, seeing as so few people use it. But honestly probably a better answer than mine.
@firefish What do you mean? How am I uncultured because so few people use the Rust programming language relative to other languages?
@xxpertHacker You are deluded. Google agrees with me:ignore the last bit
@firefish No, it doesn't?
The last sentence supports me, not you.
I'm among the 5% of people who have used the language.
@xxpertHacker but 86% of people said they were keen on learning it
@firefish Yeah, that's cool.. but they haven't started. Actons are worth more than words.
Could I have asked one of the people who are keen on learning it about the duplicate crate? No, because they have no clue what a crate even is, because they want to learn it, but they haven't started.
Thus we return to what I had originally said:
...so few people use it.
@xxpertHacker I agree. Rust can actually be a really good language if you know how to use it. Otherwise it seems like C++ but with restrictions and weird rules
@DynamicSquid Learn the rules, and you will forget how to code in C++ (lol not kidding)
@firefish lol. I like C++ since it allows you to do whatever you want. Rust is like:
Is that unsafe code!??!?! ERROR!
C++ is like:
Is that unsafe code?? Okay, lemme provide you with some additional features that you can abuse
@DynamicSquid Whoa whoa, you need to learn the language.
Once you have, you'll realize C++ is the language without restriction and with weird rules. Rust is a language that makes sense.
Also, it has one major advantage over C++: there is no undefined behavior whatsoever.
You can have a multi-threaded program, knowing everything will always run flawlessly (okay, it might deadlock, but still).
You will never run into concurrent reading/writing problems.
You should never get a system floating-point exception.
Arithmetic should never overflow and give weird results.
You can't perform certain operations in Rust, but you can in C++:
println!("{}", 'a' / 'b'); // error, what are you doing with your life?
std::wcout << ('a' / 'b') << '\n';
You can't read uninitialized data:
let x: i32;
println!("{}", x); // error
You can't read out of bounds memory.
You get where I'm going, the list continues, you can't do a bunch of dumb stuff, do you know what that means?
Every package you import and use should work correctly, without having to review the code.
It doesn't have classes, so if you like OOP styled code, you'll have to learn how to write idiomatic Rust.
@DynamicSquid Well What if you reference something you aren't supposed to, and then you program starts overwriting itself in memory. Oh boy, can that be abused
how to stuff
I wouldn't have used the verb stuff
in THAT context but whatever you say...
@firefish Oops, I edited half of the sentence without reconnecting it; fixed.
@firefish What are you talking about?
@DynamicSquid Night can be BOTH interpreted AND bytecodce
@xxpertHacker The message you deleted
@firefish It was deleted for a reason :)
@xxpertHacker I bet it ended withb stuff in that context
or something along those lines
@xxpertHacker And then you probably said something indecent in the context in which you WOULD use it.
@firefish CPython and the V8 JavaScript engine both just interpret bytecode instead of text, seems more performant, why not just use bytecode?
@firefish No, I had actually questioned how "stuff" is even a verb, before remembering that it could mean to put something into a small space.
@Dynamicsquid @xxpertHacker a.k.a. @StudentFires forgot to ping you, here's what he said:
CPython and the V8 JavaScript engine both just interpret bytecode instead of text, seems more performant, why not just use bytecode?
@xxpertHacker Oh, ok then... lol
@firefish Who's @StudentFires? And no, I was responding to your message, which was directed towards DynamicSquid.
@xxpertHacker That's you, remember? (aight this guy has memory loss)
@firefish Nope, no recollection of that Repl.it user whatsoever.
@xxpertHacker I hope you're joking because click on the link @StudentFires and you will see that it leads to your own profile
@firefish Weird, I'll probably go report that bug later, when I have time.
@xxpertHacker Explain this.
@xxpertHacker And what happened to changing repl.it at it's core
@firefish, @xxpertHacker Should unsafe programming practices be the programmer's fault, or the language's fault?
@DynamicSquid The programmer's fault in C/C++, in rust it's the programmer's fault if you put an unsafe block
@firefish I feel like it should be the programmers fault. That's why I like C++ so much, you can do whatever you want
@DynamicSquid it is the progrmammers fsualt
@firefish But... fish don't have legs...
@DynamicSquid To that, I must ask you the following:
In a strongly-typed, and statically typed language, should type safety be the programmer's fault, or the language's fault?
Should you run a compiler on a text file, and get a properly working executable, or an improperly-working executable?
Should source code that was developed on a Windows computer be capable of being compiled on a Linux, and run just as it had done on the Windows, without change?
Should undefined behavior be allowed to even exist?
@xxpertHacker Yeah, good points, can't really argue with that
@xxpertHacker But again, I think the feeling of "this language won't let me do this" is harmful since it's limiting programmers in what they can do. Programming's (I'm talking about low level programming since that's obviously the best) all about working with the computer, but if you restrict some of the things you can do with the computer, well then you're not really working with the computer, if that makes any sense
@xxpertHacker Where did I mention legs...
@DynamicSquid We can both agree on what to choose from those questions I raised, and Rust made the right choices.
Simply think of the restrictions like you think of what you can do in C/C++ on a pointer.
Let's start, what is a pointer?
Computers only understand numbers, a pointer is a literal integer, yet... in a way, it's not.
It is an integer, yet it simply is used to load and store memory at the specific point that it "points" to.
Why do I bring this idea up at all?
Because they are an abstract idea, but they have restrictions.
char const * const x = "test"; "test\0"
decltype(auto) est = test + 1; // "est\0"
decltype(auto) questionableCode = test >> 3; // not allowed, yet... allowed on integers
decltype(auto) moreQuestionableCode = test & 1;
Does that seem like a weird restriction? Hopefully not. Yet it makes perfect sense to restrict what can be done in some cases, yet most of the time, C++ just lets you do whatever you want, whether or not it makes sense at all.
@firefish You said that I was "pulling your leg," but you're a fish.
@xxpertHacker give him a couple million years and he'll grow legs
@DynamicSquid You will too, right?
@xxpertHacker No, squids can't evolve. If you look closely at the hierarchy:
class Cephapod final // notice the 'final' keyword here
: public Animal;
@xxpertHacker So there are these things called idioms
@firefish Whoa, idioms of the sea? I don't know many fish idioms, sorry.
@xxpertHacker But the whole point is not having restrictions. If I want to shift bits, I should be able to shift bits. The idea of "abstraction" I think is just a way for me to better communicate what I want to do with the computer
@DynamicSquid Lmao, you can be the first by learning Rust though.
@xxpertHacker Are you THAT dumb
@firefish No, I'm dumber.
@firefish, @xxpertHacker I am so confused, we're having like 2 conversations at the same time
@DynamicSquid @xxpertHacker is trying to annoy me, by being an idiot
@DynamicSquid Yeah... it could be confusing for you, being caught in the middle, and being the author of this post, meaning you get every message.
@xxpertHacker, @firefish you guys making fun of each other reminds me:
your mamma is so fat that she can sit on a binary tree and turn it into a linked list in O(1) time
@DynamicSquid lmao lol
@xxpertHacker, @firefish gotta go now. probably gonna come back to like 50 notifications :/
@DynamicSquid we won't annoy you, will we @StudentFires?
@DynamicSquid The idea isn't restriction at all, more likely, it's explicitness.
Often times, in source code, when you see something weird, one of thee things are true:
- You stopped and said, "what am I looking at?"
- There is a comment explaining the apparent nonsense, explaining that it is not nonsense, but some weird technique.
- You actually understood what you saw, because you've seen it before, or had actually done it before.
If you've ever seen a weird piece of code before, you should agree.
The first possibility is very likely, and it exists because languages let people do weird stuff. This possibility does not exist within Rust.
The second exists for the same reason as the first and is due to a lack of language-level support for whatever they did, or because they were lazy. What if you provide language-level support for this?
The third possibility is very unlikely and doesn't need to exist, because weird code practice shouldn't need to exist.
@DynamicSquid We're not even making fun of each other.
Hi, don't mind me just testing a bot
Hi, don't mind me just testing a bot
sorry if it is java then i can't help as i have not yet learned it!!
sorry :(
@TANMAYBAGADIA why did you reply then lmao
@TANMAYBAGADIA Thanks for the help lol. But you can do this in any language
@DynamicSquid oh ok ,but sorry i was not able to give u answer
I feel like what should happen is (you forgot your semis, that bothered me a lot):
class LandSquid
{
private:
SomeTypeEnum advanced;
public:
void DisplayInfo() {/* use that advanced variable to customize */}
void move() {/* technically it would be swim, but this is called consistency */}
};
class AquaticSquid
{
private:
SomeTypeEnum advanced;
public:
void DisplayInfo() {/* use that advanced variable to customize */}
void move() {/* technically it would be crawl, but this is called consistency */}
};
and you now see you could even make this only one class! Maybe even polymorphism idk
@Coder100 Also what is SomeTypeEnum advanced
?
the type, land or water @DynamicSquid
@Coder100 if statements would just get too ugly, no way
@Coder100 if statements means I would need to pass in parameters, and it couldn't work well with other interfaces, and it's not modular, etc.
hm, maybe im not understanding your question right, sorry :( @DynamicSquid
i was thinking them more similar than not sorry :( @DynamicSquid
@Coder100 what can I clarify?
do they all have similar moves? @DynamicSquid
advanced squid for land and aquatic have same moves just reworded and same for basic @DynamicSquid
@Coder100 what is this
public:
void Swim();
nonsense just usepublic void Swim()
:woh no the old VIM habits
@firefish i mean in C++ that's what we do
@Coder100 Well that's my C# brain for you then
@firefish I hate Java and C# for making people do this:
class T {
public void foo() { ... }
public void bar() { ... }
public void baz() { ... }
public void quux() { ... }
}
When C++ just says:
struct T {
void foo() { ... }
void bar() { ... }
void baz() { ... }
void quux() { ... }
}
@xxpertHacker exactly, it's so annoying
@Coder100 no the whole point is that they're different functions
@xxpertHacker what the hell in C# structs can have methods
@firefish In C#, What is the difference between a struct and a class?
@xxpertHacker Structs are inline, and classes are allocated on the heap.
@firefish Hmm... well, I was using C++ structs as public classes.
Even then, it could've been this:
class T {
public:
void foo();
void bar();
void baz();
void quux();
};
Still less typing.
@xxpertHacker Is you ask me, that public:
thing looks out of place and hideous
looks beautiful @firefish
@Coder100 did you mean @CSharpIsGud instead of @C#?
@firefish Thus why I simply prefer using the struct keyword in C++ instead, it implies it already, while not looking weird.
But still, public
/private
fields are better than tediously putting them one by one.
@xxpertHacker In C++ structs can have methods too, only in plain C you cannot
@firefish In C++, structs are perfectly equivalent to classes, with one difference. They are public by default.
class T {
private: // redundant
};
struct T {
public: // redundant
};
So, yes, it makes perfect sense that they would have methods.
Although, C structs can be used as namespaces, by using function pointers.
struct T {
int const (* const method)(T const);
};
Eh, still not a method.
@xxpertHacker Yes, still not a method.
But in Rust there are no such thing as classes! Only structs and enums, in which you can implement wither your own methods, or a trait (the closest thing rust has to an interface)
me likey c++ rust not make me commit unsafe @firefish
@Coder100 do what you "likey", grilled cookie (or is it cookey now?)
@firefish You can, it's just ugly because you have to use function pointers.
If you really want to you can give them self references as the first argument.
@xxpertHacker structs are value types, no default constructor, new operator isn't needed to make them, they can't inherit from structs or classes, no non-static variable initializers
@CSharpIsGud Assuming you're talking about C# structs, that'll be worth keeping in the back of my mind, should I ever find myself debugging C# or learning the language.
Also, I presume the unnecessary new
is because they aren't heap allocated, is C#'s new
related to heap allocation at all?
@xxpertHacker I think they just did new because it was a thing, new doesn't really make a difference.
C# can allocate structs on the heap if they are located inside a class.
@CSharpIsGud Well, of course, if a class instance is heap-allocated, then I would expect all of its members to be on the heap too, including structs.
But, since you're here, and you use OOP styled code (right?), you seem like you would be among the most capable programmers here capable of helping out @DynamicSquid with his question.
@xxpertHacker even in C# I avoid inheritance everywhere possible unless it actually makes what I want easier.
Table (for reference)
aquatic | land | |
---|---|---|
basic | basic-aquatic | basic-land |
advanced | advanced-aquatic | advanced-land |
for others, i made a tiny table:
well that's just great tables aren't supported no more
well that's just great i forgot how to do tables
@Coder100 wait I though tables didn't work here
apparantly my brain broke @DynamicSquid
anyways check out the other comment imma try to think of how to solve your problem @DynamicSquid
Version | Description | Progress |
---|---|---|
v1.0 | functions to aid with arrays | complete |
@Coder100 oh ok nvm they work
anyways check out my answer is it even good @DynamicSquid
hol' up i thought this was C++, and then i looked at the interface and I was like oh wait nvm @DynamicSquid
@Coder100 it doesn't matter what language it is
ig
did it help tho @DynamicSquid
@DynamicSquid that would be pog if my ideas actually came to life :D
@Coder100 But in your example you combined Swim and Crawl, but they need to be separate functions
wait but you could add if statements:
if (type == WATER)
{
//
}
else if (type == LAND)
{
//
}
wait why not @DynamicSquid
@DynamicSquid lol le sqdlib (also come onto le pr #65 on NIGHT)
@Coder100 No if statements, THIS IS A FLIPPING INTERFACE, you can implement them how you want, so move() does different things depenfing on whether it's land or water
I personally don't use classes, I don't know why, I just don't like OOP code, but, I recommend just using whatever is simplest and most maintainable.
...
Honestly, I sat here for more than 15 minutes, trying to think of a good way to create these interfaces, but nothing sounds good.
I have no clue how you should do this, maybe go look at some gaming industry's source code?
Although, maybe it's hard to understand it because of the lack of information.
What makes a squid advanced or basic?
How different is an aquatic squid from a land squid?
Depending on how you define the differences between them, you might not even need separate classes at all.
@xxpertHacker The main difference are the functions. Each class has it's own unique set of functions. For example
AquaticSquid
hasSwim()
,Drown()
, andFloat()
. I'll try to reduce the number of functions I have, but for the time being, each class has it's own funtcions.@DynamicSquid I'm not sure if this is a good way of setting it up, although, I am not a game developer either. (This is a game you're attempting to program, right?)
Now, I have no clue how your game is going to work nor do I have many details, but if the squids are capable of battling each other, ideally, you would want a generic setup that would allow you to pit any two squids or players against each other, at runtime, without compiling a separate code template for every single possible combination of creature that could meet.
Let's say the core of the game revolves around pitting squids against each other (wait this sounds like Pokemon or something, eww), you have a function called
battle
.It takes two formal parameters, each being the squid to take a side in the battle.
How would you set it up, if each squid has different methods? Duck typing isn't safe. And compiling something like
battle<Squid1, Squid2>(Squid1 squid1, Squid2 squid2);
for every possibility isn't fun either.Also, in every game that I've played, to date, every different player could all do similar things at a high-level, they just have different animations.
Think of a shooting game, each firearm deals damage, and has velocity, yet they have different animations, sounds, trajectories, and numbers associated with their capabilities.
Personally, I might do something generic, like
.move
,.primaryAttack
,.secondaryAttack
,.canSwim
, and give them all different implementations, but I'm not sure if it's the best way to do this, or if anyone else would agree with a structure like this.@xxpertHacker It's not really a game, more like a "museum" lol. But yeah, I think you're right. I want polymorphism (what's short form for "polymorphism"? is it "polymorph", or can I say "poly") to work as well, so I probably have to make generic methods.
Thanks for the help though!
@DynamicSquid Oh, oops, I presumed that it was a game, or something of the sort based on your initial example:
BasicAttack
seems like something that you would find in game, and considering that we're on Repl... it wouldn't normally be a bad guess.But, good luck with your program!