|
honey the monster, codewitch wrote: i mean procedural as in procedures rather than objects to divvy up code. That's a non-complaint; like I said, you can put all your procedures in a God-object.
honey the monster, codewitch wrote: If there's a better word for that I'm unaware of it. You could say that all imperative languages are procedural if they have functions/methods but that's almost too general to be useful. I'd say you haven't worked in a strict procedural language
honey the monster, codewitch wrote: As far as your yucks, i come from a C++ background and happen to like generic programming. to each their own. Haven't seen much of that, so not going to comment on it. But still, yuck.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|
Eddy Vluggen wrote: That's a non-complaint; like I said, you can put all your procedures in a God-object
Not a complaint. Just attempting to clarify what i meant
Eddy Vluggen wrote: I'd say you haven't worked in a strict procedural language
Now I wonder what you'd consider procedural. Batch files? SQL? C?
Eddy Vluggen wrote: Haven't seen much of that, so not going to comment on it. But still, yuck.
Spoken like someone that's never used it. GP is lovely, elegant, concise and powerful. I wish it was more available in places other than C++.
When I was growin' up, I was the smartest kid I knew. Maybe that was just because I didn't know that many kids. All I know is now I feel the opposite.
|
|
|
|
|
honey the monster, codewitch wrote: Now I wonder what you'd consider procedural. AMOS, among others.
honey the monster, codewitch wrote: Spoken like someone that's never used it. OO is the most logical step forward from the messy and hard-to-maintain pages of procedures, sprinkled with arguments and global variables.
honey the monster, codewitch wrote: I wish it was more available in places other than C++. It is still available; you can abuse any OO language as if it is merely capable of procedures.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|
generic programming, not procedures.
When I was growin' up, I was the smartest kid I knew. Maybe that was just because I didn't know that many kids. All I know is now I feel the opposite.
modified 31-Jul-19 7:40am.
|
|
|
|
|
But I want an atheistic classless society.
|
|
|
|
|
10 GOTO HELL
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|
heh
When I was growin' up, I was the smartest kid I knew. Maybe that was just because I didn't know that many kids. All I know is now I feel the opposite.
|
|
|
|
|
I learned OO before it was (generally) known. I didn't learn it by that name.
Our "101 Programming" course was based on Pascal. The professor insisted that we wrote sets of functions for each RECORD definition, for handling that record type. He also insisted that these fuctions took as their first argument the specific record instance to be operated on. We learned it as a good way to handle the information in a managable way. It was similar to his other requirements: Function arguments should list the read-only inputs first, then the read-write, then the pure results. Every function/subroutine should first check all input data, then do the work, then produce the side effects.
We learned that as a valuable discipline. We never questioned it, and today I can't give a single argument why we should have.
Then came OO, and we moved the first function argument before the function name, with a full stop inbetween. Fair enough - "a new programming paradigm", or "syntactical sugar", call it whatever you want.
At the University, we got hold of one of the very first C++ compilers, translating everything to K&R C, so we could see what OO really is - and said: So what? Isn't that what we have been doing all the time, more or less? There were some extensions, of course, but not that revolutionary.
I got my first job, in a company writing their own OS for their own minis and superminis, written in a langugage midway between plain C and assembler. What did I see? Those OS programmers had created the same kind of "OO" structures at near-assembly level, very similar to what I had seen in the C++-to-C translations, with class objects and inheritance with subclasses and superclasses and function tables and whathaveyou. (No multiple inheritance, but that is a concept that is highly debated anyway.)
When I, as the novice with academic ideas, tried to tell them that "This is exactly like OO programming", they didn't grasp the idea, at the academic level. It was just the proper way to do it. Similar to the way it was thought in my first "101 Programming" course.
So I never managed to build up any negative relationship to OO. Only to those programmers who insist that there is One OO Way, or demand that you must use every single OO feature in your program, now matter how primmitive the program is.
Maybe I am too relaxed. That allows me to pick from OO what is usable in a given case, and ignore the rest. I think that is good.
|
|
|
|
|
I definitely hear you, and though I got my start less formally, and in the 1980s I worked out a lot of the same observations that you did about OO.
My problem isn't OO specifically, I guess it's more that OO languages (outside, say C++) tend to treat that as first class at the expense of everything else.
And really, OO isn't my first go-to for solving a problem. I speak in templates - generic programming a lot - it's just often a more elegant way to code, and solves a lot of needs of both imperative and functional programming in practice.
So when I don't have it, I mourn it I guess. It's still that Thing(TM) that keeps calling me back to C++. Oh but I wish for a higher level language that I could do with what I do with C++.
Give me something like C# that works with something like STL and I will be in heaven.
That's what I want.
When I was growin' up, I was the smartest kid I knew. Maybe that was just because I didn't know that many kids. All I know is now I feel the opposite.
|
|
|
|
|
at the risk of being controversial, I will say: procedural vs object oriented = potato vs tomato
Think of Math.Cos(), the fact that Cos() is part of the Math class is not really limiting and artificially constrained by object oriented programming. It's just that the function need be somewhere...
I guess I used to feel limited by the number of class I could call "Utils" but I overcame this challenge long time ago!
generic limitation: I did notice that when my code become excessively generic it snowball and become more unmaintainable. I did notice that C++ specialization would be a nice touch that is missing. And I also hate boiler plate repeated code.
But strangely enough since I noticed that I had no further problem... maybe I unconsciously found working alternative? I guess it might means there might be a solution to the problem you are facing...
|
|
|
|
|
the problem I'm running into right now regarding specialization i had to work around by using a common base class to "share functionality" and it doesn't work very well. I have a lot of duplicated code in the specialization, and i've had to use "new" on some methods. It's rather awful, actually.
Luckily most of the time, I can avoid the need altogether but in this case, specialization would make the most sense, so i did my best to "make it work"
it's baling wire and chewing gum compared to what i can do in C++
I guess for me, once I relearned C++ the way it's taught in Moo and Koenig's book, I used generic programming for most of my coding.
It doesn't make maintenance snowball. If it does, you're probably using it wrong and I highly recommend Accelerated C++ by the two authors I alluded to above. It's worth every penny of the $20-$30 asking price and you can usually get it used for a song.
It's also a mercifully short book. It's one of the best programming books I've ever encountered for that - it's concise, accessible, and teaches something that's not typically taught well (C++ programming)
But alas, using C++ the way they show you to use it makes me miss being able to do things that way now.
When I was growin' up, I was the smartest kid I knew. Maybe that was just because I didn't know that many kids. All I know is now I feel the opposite.
|
|
|
|
|
As someone else mentioned, have you considered using interface?
Interface offer some of the benefit of multiple class inheritance without any drawback or ambiguity.
|
|
|
|
|
for this particular problem I don't really need multiple inheritance. I have a single inheritance chain.
Frankly, what I need is template specialization and if i had it there'd be no inheritance at all.
The use of FA as the base class is just a way to drag common code between the main FA and the CharFA specialization
the FA serves as the base class and the main class. The CharFA inherits from FA and specializes it.
It's ugly under the hood but it works.
The why of this would be easier to explain with a background in finite automata and regular expression engines
When I was growin' up, I was the smartest kid I knew. Maybe that was just because I didn't know that many kids. All I know is now I feel the opposite.
|
|
|
|
|
so you have (taking a guess in the dark)
public class SomeParsingData {}
public class FA<T>
{
public virtual void MyOperation(SomeParsingData data) {}
}
public class CharFA : FA<char>
{
public override void MyOperation(SomeParsingData data) {}
}
static class FAUtil
{
public static void MyOperation<T>(FA<T> target, SomeParsingData data) => target.MyOperation(data);
}
And you are lamenting that MyOperation() implementation is in FA instead of FAUtil class. Is it?
Particularly when FA and SomeParsingData are not really related but both needed in MyOperation, right?
Thinking about it... But not thinking too much until you confirm your issue...
|
|
|
|
|
Actually I have only two classes, with
class FA<TInput,TAccept> {
}
and
class CharFA<TAccept> : FA<char,TAccept> {
}
Most of the time, the second class delegates to the first.
Sometimes it has to overload what the base does. Sometimes it changes the function signature or "overloads" a static method so i have to use the "new" keyword.
When I was growin' up, I was the smartest kid I knew. Maybe that was just because I didn't know that many kids. All I know is now I feel the opposite.
|
|
|
|
|
In answer to your question, I'm lamenting that
a) i can't share more code. i'm overloading way too much in CharFA
b) the two classes are distinct when they shouldn't be
I'd much rather have
var fa = new FA<char,string>();
var fa = new CharFA<string>();
both issues would be addressed by using partial template specialization in C++
When I was growin' up, I was the smartest kid I knew. Maybe that was just because I didn't know that many kids. All I know is now I feel the opposite.
|
|
|
|
|
It's funny... I remember once I had generic code that look kind of like that
void DoSomething<T>(T value) {
switch (typeof(T)) {
case typeof(double): DoDoubleThing((double)value); break;
case typeof(int): DoIntThing((int)value); break;
default: DoDefaultThing(value); break;
}
}
But after some refactoring this all went away...
I know, not helping, just sharing!
|
|
|
|
|
there's a kind of switch for types in newer C# but i've not used it yet. that might have been what it was.
unfortunately it doesn't solve my problem =/. I think i've worked around it well enough, i just wish i had something better. if i ever come up with a trick to solve it i may publish here about it.
When I was growin' up, I was the smartest kid I knew. Maybe that was just because I didn't know that many kids. All I know is now I feel the opposite.
|
|
|
|
|
isn't that similar enough to template specialisation?
class A<T>
{
public virtual void Do(T value)
{
Console.WriteLine("Value: " + value);
}
}
class B : A<int>
{
public override void Do(int value)
{
Console.WriteLine("Int: " + value);
}
}
class Program
{
static void Main(string[] args)
{
A<int> a = new B();
a.Do(1);
}
}
|
|
|
|
|
that's exactly what I want. Does .NET support that now?
When I was growin' up, I was the smartest kid I knew. Maybe that was just because I didn't know that many kids. All I know is now I feel the opposite.
|
|
|
|
|
I dunno if there was a problem before.. but it's copy paste from some code I was just running on a test project while thinking about your problem....
So, shortly, this is fine.
Assuming it was not always working (which I doubt) the test project use .NET Framework 4.7.2 and C# compiler latest version, i.e. 7.3
[EDIT & REMARK]this looks like perfectly valid C# since the beginning of generic to me. Odds are you got confused at some stage...
modified 31-Jul-19 0:36am.
|
|
|
|
|
i looked at your code wrong, didn't notice until i tried writing one myself. that's not template specialization, but simply method overloading - and i'm doing it already
class CharFA<taccept> : FA<char,taccept> {
..
}
When I was growin' up, I was the smartest kid I knew. Maybe that was just because I didn't know that many kids. All I know is now I feel the opposite.
|
|
|
|
|
Yeah, I was wondering, isn't that good enough?!
But then I realised one could accidentally instantiate new FA<char, T>() instead of the desired new CharFA<T>()
But then what of this other syntax?
While it's slightly more wordy, I bet the end compiled result is just as you desired
class A<T>
{
public void Do(T value)
{
if (value is int intV) Do(intV);
else DoDefault(value);
}
void DoDefault(T value)
{
Console.WriteLine("Value: " + value);
}
void Do(int value)
{
Console.WriteLine("Int: " + value);
}
}
class Program
{
static void Main(string[] args)
{
A<int> a = new A<int>();
a.Do(1);
}
}
I mean personally I am happy to solve that using subclasses or interfaces, but since you really didn't want to....
|
|
|
|
|
Yeah I can't do that in this code because this code is inner loop critical and the "is" comparison is just a dog. I think "as" is faster, but still, it should be resolved at compile time.
I know it seems a minor quibble but this code may be used as part of a lexer. The lexing itself needs to be balls quick to be feasible.
also i'd be concerned about bugs this could introduce since i have to repeat a lot of code, but that's not a showstopper. it's just irritating
When I was growin' up, I was the smartest kid I knew. Maybe that was just because I didn't know that many kids. All I know is now I feel the opposite.
|
|
|
|
|
I think you probably underestimate the compiler here
generic code are some sort of IL that is used to generate code on demand (when a concrete type is used)
when, say A<int> type is created the compiler will see that
void Do<int>(int value) {
if (value is double d) {
}
if (value is int ii) Do (ii);
} some path will never happen and it will removed them from the concrete implementation created when the concrete type is created.
and the compiled code will become
void Do<int>(int value) {
Do (value);
}
|
|
|
|
|