> Pay attention to which operations are expensive > for the various data structures (map vs. list vs. > vector, etc.).
This is hope-fully implicitly understood by users of data-structures, at least if they are able to code C++:)
What you should remember, is to utilize the C++ methods for type-alias: typedef, to make it much easier to swap data-structure implementation, and or even parametrize by the data-structure as a template param (often with a default).
> The biggest downside of the Standard Template > Library is that it isn't very standard.
No, but the C++ Standard Library is in ISO14882 ("Programming Languages -- C++"), and it "superceeds" and embraces the old STL. Unfortunatly most people (and tutorials) still refer to either the STL definitions or use the term STL about the standard library.
> The support for templating, across a range of > compilers, just isn't very consistant, which > makes using the STL in a portable manner > almost impossible.
Depends on what you use. Normally, it's not the containers themselves. that makes trouble, it's the functors and the algorithmic versions of operators (i.e. std::less and such), which most programmers don't use for the first few months.
BTW: GCC-3 has EXCELLENT template-YOUR_FEATURE_HERE support as well as standard library support.
> Aside from that, the STL is, to my mind, just > another giant complex wart on top the > mind-numbing complexity that is ANSI C++ itself.
C++ is complex because of the possibilities it offers... well, and it's heritage. To the untrained even the simplest tasks are compilcated... think how long it took to understand (not just learn) multiplication:)
> As with OOP itself, generic programming is a
Hmmm.... I consider generic programming perpendicular to OOP (this is a nice analogy when explaining why using GP from OOP sometimes requires "multi-dimensional" programming... if you understand?)
> Really Good Idea(TM) but its implementation in > C++leave something to be desired for simplicity > ans accessability.
Agreed, as well as consistence in compile-time versus runtime versions of syntax.
> Due to C++'s dominance in the marketplace, the > STL will likely be with us for many years, but > this is far from a desirable circumstance.
The Standard library (not STL) is the best thing that happened to C++ for years. I doubt it could have been done cleaner and more flexible in C++?
I would like to see optional garbage collection (with fitting restrictions to legal programs) introduced into C++. That's the no. 1 thing holding back (advanced/modern) OOP in C++.
It's a (GOOD) marketing brand for a loose set of unrelated ways of trying to solve complex problems in the field of application programming. Not much more.
XP will work for talents (and a few trainees) who, if left alone, would probably work somewhat like that, not for "people" in general, and especially not for the workplaces that need a "development model", and sees XP as a Solution (yes the "S" is on purpose:).
Although people in general (especially the one who should not use XP) think it's great -- I fail to see the benefits, beyound rationalizing and "memorizing" the way talent's work.
Educated: Someone with a vast knowledge about a problem-domain, and means (often approximating algorithms) to recognize problem/solution pairs.
Talent: Someone who "just does stuff", doesn't have to think about it. Often turns out to outperform educated people by doing "The Right Thing", even when they should not be able to:)
Educated Talent: Rare! explosive mix! Hire at all cost!
PS: I don't think of myself as talented at more than 2-3 (smaller) things/fields.
If virus'es are only scary, it's because the virus writes are amateurs.
Vira could be a lot more smart:
1. multiple targets/entry points
- exploit varying holes in a heterogene environment
2. morphing
- Using nondeterministic compilation you could create vira that would be virtually impossible for scanners to identify -- shape-shifting for every infected computer/file.
3. incubation time
- Vira which we have seen recently don't have much of an incubation time
4. Social engineering
- Look at the "SULFNBK.EXE" (non)vira. Vira that infects this file will probably be a lot more likely to survive for at least a few years.
5. Centralization/automation
- As we adopt digital signatures and auto-updates of programs and operating systems, we are creating the perferct transfer media for vira.
6. All the stuff i didn't think of in 10 mins.
Fortunatly, it seem it's mostly intellectually inept people who make vira (YES, I mean that - if some "real" people did it it would be MUCH! more dangerous).
How would that be better tthan solar cell's on earth?
If they were on earth, at least, you don't have to launch them, you don't have to defend them furiously against space-debree, no fancy microwave power-transfer device,... (make up more yourselves).
Evolution (as we know it) is set out of effect in the "rich" parts of
the world, where medicine and social security now are much more
important than traditional evolutionary "virtues" like strength, resilience
and other stuff like that.
Many rich countries help those of their inhabitants unable to
reproduce themselves via various medical techniques, people who are
sick are personally cured by medicine, allowing them to breed
offspring that is more susceptible to disease.
This is altering the forces which evolution operate under to be more
about money and knowing good doctors,... , than about genetically transferred individual
abilities to survive.
To some extent these values: money and good doctors,... are
individually transferable, via heritage and social bonds (family), and
thus somewhat relate to genes.
We may just see another kind of evolution, based much more on social
position, than on genetically transferred capabilities, making an
impact over the next 50-100 years.
I'm not saying this is the way I would like it to be, just that might
be possible.
As I don't have much actual knowledge in these fields, don't take the
predictions to serious, but I wanted to share them anyway, so that I
can discuss them and learn.
A lot of the posts here are angry at Nick Moffitt for doing what he does. But I side with him:
If you wan't to be part of something he does, you have to play by his rules. I can't see anything wrong with that. If you wan't to use Outlook you have to sign an agreeement, even if you link with GPL code you have to "play by the rules"...
Evolution will decide what good/harm he does, and there's nothing you can (or should) do about it, except act according to your beliefs.
Many of the comments in this discussion states that it's hard to write a portable and yet well-performing compiler, as an argument defending GCC.
There simply no substance to that argument. Any optimization you can do in a target-specific compiler can be done in a portable compiler, simply by only performing it when it's known to be valid.
It's not "harder" to optimize in a portable compiler, but there's a lot more targets to cover, and thus much more work to be done. And I think that's probably the actual problem that GCC has, compared to Intel.
BTW: I'm no GCC-fan, but I like it for it's (relative, compared to Borland, MSVC and Sun compilers) C++ standards confomance, and for the best error-messages (call/inclusion tracking for templates/headers).
This assumption set's focus in the wrong place. Most projects have low algorithmic complexity and many of those fail. so that's not the actual problem.
It might become a problem when people in the software world start solving hard (algorithmic complexity-hard) problems -- but I don't see that happening in commercial mainstream software within my lifetime;)
To make any kind of sense, the "==" relation would have to be transetive, since his arguments about what "confused" him used that property.
It's probably also reflective, since an extrinsic definition of equality (the one used in the relation) should be a sub-relation of the intrinsic equality, that is the one we use to compare elements in our universe (in this case the language). And we prefer any string "Linux" to mean the same as any other string "Linux".
I don't see him using the (normally usefull) symmetry property, which would make == an equlity relation, so I cannot assume that's a property of the relation... it may be, nobody knows,.... he has not defined the relation, which is what leads him into trouble in the first place... and me into laughing;)
Your statement has nothing whatsover to do with a new "branch" of logic, and can be treated in ordinary first-order logic.
Every time some under-graduate starts algebra or logic courses, this idea (A != A) or (A -> !A) or something like that arise, and in some cases the student even understands why it's funny, and learns from it. Well let's hold hands as we look at it:
Let us work in the universe U with at-least one element, and no upper bound to the number of elements
The interpretation of the axiom "A != A" is:
"no intrensicly equal values are extrensicly equal", since it is shorthand for the axiom:
forall x in U: x != x
Where two elements in U are compared with "U"'s equality relation (lats call that =A), and the statement "x != x" is evaluated in the relevant logic's definition of "!=" (lets call that !=B).
Normally the definition of "!=" is formulated in terms of the equality defined by U:
forall x in U: (forall y in U: (x !=B y if and only if !(x =A y))
Which very nicely make extrinsic and intrinsic equality the same relation, provided that the used logic is poverfull enough ( in other terms, extrinsic equality is a sub-relation of intrinsic equality)
So the statement (A != A) claims that the logic can distinguish between to instanses of the same element from U, which is utter rubbish!
This statement will of-course convince noone (at least if the are pedantic, and thus good students;), so let's take the usual Heidelberg Propositional Logic (Let's call that Hprop) and extend it with axiom "A != A" (call that Hprop') and prove that Hprop' is not sound.
Let x be any element in U. By equality and confounding axioms and the axiom of "&&" we have:
(((A == A) && (A != A)) ->* (A == A) && !(A == A))
So Hprop' proves
B & !B
But:
B & !B -> false
So via the deduction lemma, we have shown that Hprop' proves false.
Let us note, that Hprop is sound and comlete, and therefore no sound first-order logic can contain the axiom "(A != A)".
When one wishes to illustrate a missing point in a question, it's commonly known as rethorical trick to rephrase the answer as a "Counter-question" which will help "the other guy" see problems in the question.
This rhetoric is related to the rhetoric of analogy, allowing you to "reason" about something without explicitly mentioning your arguments (which would be a long story about the value of Open-Source and stuff).
The original question was (stated in the post) posed in a way that could be understood something along the line of "Well, if linux is so good, then point me to a place where they use it (seriously)", implying a lack of value to the "linux product".
Since WinMe is not installed in corporate environt, chances are you will not be able to think of a "large installment" of WinME. But the person who posed the question will most likely hold that WinME has value! The "poser" of the question will now not be able to make the argument : "no large installment implies poor value" (without implicating WinME == poor value).
Most of the time, discussions are not based on presenting arguments, but on pushing rhetoric against non-believers -- this is a tactic many people use when they don't agree with the other part of the discussion (Just look at GPL zealots vs. M$ zealots).
But are we ready? We know surprisingly little about the social and psychological impact of e-mail, beyond usage, volume and demographics.
Well, this should come as no surprise. The human race has a habit of not "being ready" for it's inventions. I actually suspect that's what progress is all about;)
Why does everyone (especially in the Open Source community) try to force Gnu/Linux into the dominating place for OS'es?
Unix OS'es have limited application, because of their close relation to POSIX. I.e the usage of Linux (the kernel) in embedded systems is extreme bloat (although the nerd in me would like that linux-wrist-watch).
When will people realize, that an OS is like any other tool, and you should select the right tool for the job, not the same bloated tool all the time.
Flerbage: I have the condition of flerbage when I can behave in the confidence that nobody will take my life, my physical property, or my time without my consent.
Make up any posistion, what so ever on copyrights, programs and freedom.
If you follow the rules according to that position, your (so-called) "flerbage" will not be affected in any way, what, at all.
So, you don't want to test what maximizes "flerbage", it's simply misleading to even enter that definition into the convesation.
What you really wan't to do, is list the requirements of the interested cotegories:
User
Stable software
Helps "Use" the software
Minimum Price
Helps pay bills
Software that's best suited for individual use
No two people work alike
Minimum hazzle
Software should "just work", like lights and phones
Integration (not in the Windows sense: it's integrated, so you have to use it all. But in the real sense: if you have both A and B, they will cooperate on common data/computation/interface)
Share producst from different software producers
Developer
Ability to use existing solutions
Dont do work that others aready did
No restrictions on produced product
Ability to control your creation
Control over the usage of created product
Allows you to make monty
Corporation
Earn Money
Enhance Image (i.e. Give users, developers or society what they want)
Soceity
Increase BNP
A wealthy country is a healthy country
Keep voters happy (Let's face it, mainly users)
Another term in power please!
Keep cooperations happy
At least in the US, they paid the campaign
Now all you have to do, is keep adding things to the list and maximize the "happiness". No wonder there are so many conflicting solutions to an equation without a single maximum in all the dimensions.
You may wish to be a little more clever than that, grep'ing the entire log-file every time someone invoked the script is not a good way to determine it you've been hit or not.
Proposition 1:The number of times your web-server is attacked is a compositional function of the log entries.
What prop. 1 tells you is, that to you may directly apply the "divide and conquer" strategy to the problem, analysing parts of the log-file seperatly and composing the application of your counting function to each part by the binary operator "+".
This tells you, that once you have visited a part of the log-file, you will never have to visit that again, so maybe your program should look something like:
Forward till the place I got to last in the logfile
Look at every entry after that, counting attacks
Add that to the current total (with a default value of 0)
Set the indicator to where I got to in the log-file
Print the total
Of course, you need to look out for synchronization in this version of the program, but it won't grind your server to a halt when 3-4 people press the "Number of code-red worms deflected" link at the same time
> Pay attention to which operations are expensive
:)
> for the various data structures (map vs. list vs.
> vector, etc.).
This is hope-fully implicitly understood by users of data-structures, at least if they are able to code C++
What you should remember, is to utilize the C++ methods for type-alias: typedef, to make it much easier to swap data-structure implementation, and or even parametrize by the data-structure as a template param (often with a default).
> The biggest downside of the Standard Template
:)
> Library is that it isn't very standard.
No, but the C++ Standard Library is in ISO14882 ("Programming Languages -- C++"), and it "superceeds" and embraces the old STL. Unfortunatly most people (and tutorials) still refer to either the STL definitions or use the term STL about the standard library.
> The support for templating, across a range of
> compilers, just isn't very consistant, which
> makes using the STL in a portable manner
> almost impossible.
Depends on what you use. Normally, it's not the containers themselves. that makes trouble, it's the functors and the algorithmic versions of operators (i.e. std::less and such), which most programmers don't use for the first few months.
BTW: GCC-3 has EXCELLENT template-YOUR_FEATURE_HERE support as well as standard library support.
> Aside from that, the STL is, to my mind, just
> another giant complex wart on top the
> mind-numbing complexity that is ANSI C++ itself.
C++ is complex because of the possibilities it offers... well, and it's heritage. To the untrained even the simplest tasks are compilcated... think how long it took to understand (not just learn) multiplication
> As with OOP itself, generic programming is a
Hmmm.... I consider generic programming perpendicular to OOP (this is a nice analogy when explaining why using GP from OOP sometimes requires "multi-dimensional" programming... if you understand?)
> Really Good Idea(TM) but its implementation in
> C++leave something to be desired for simplicity
> ans accessability.
Agreed, as well as consistence in compile-time versus runtime versions of syntax.
> Due to C++'s dominance in the marketplace, the
> STL will likely be with us for many years, but
> this is far from a desirable circumstance.
The Standard library (not STL) is the best thing that happened to C++ for years. I doubt it could have been done cleaner and more flexible in C++?
I would like to see optional garbage collection (with fitting restrictions to legal programs) introduced into C++. That's the no. 1 thing holding back (advanced/modern) OOP in C++.
--
Helge
Extreme Programming.
:).
:)
It's a (GOOD) marketing brand for a loose set of unrelated ways of trying to solve complex problems in the field of application programming. Not much more.
XP will work for talents (and a few trainees) who, if left alone, would probably work somewhat like that, not for "people" in general, and especially not for the workplaces that need a "development model", and sees XP as a Solution (yes the "S" is on purpose
Although people in general (especially the one who should not use XP) think it's great -- I fail to see the benefits, beyound rationalizing and "memorizing" the way talent's work.
Educated: Someone with a vast knowledge about a problem-domain, and means (often approximating algorithms) to recognize problem/solution pairs.
Talent: Someone who "just does stuff", doesn't have to think about it. Often turns out to outperform educated people by doing "The Right Thing", even when they should not be able to
Educated Talent: Rare! explosive mix! Hire at all cost!
PS: I don't think of myself as talented at more than 2-3 (smaller) things/fields.
If virus'es are only scary, it's because the virus writes are amateurs.
Vira could be a lot more smart:
1. multiple targets/entry points
- exploit varying holes in a heterogene environment
2. morphing
- Using nondeterministic compilation you could create vira that would be virtually impossible for scanners to identify -- shape-shifting for every infected computer/file.
3. incubation time
- Vira which we have seen recently don't have much of an incubation time
4. Social engineering
- Look at the "SULFNBK.EXE" (non)vira. Vira that infects this file will probably be a lot more likely to survive for at least a few years.
5. Centralization/automation
- As we adopt digital signatures and auto-updates of programs and operating systems, we are creating the perferct transfer media for vira.
6. All the stuff i didn't think of in 10 mins.
Fortunatly, it seem it's mostly intellectually inept people who make vira (YES, I mean that - if some "real" people did it it would be MUCH! more dangerous).
How would that be better tthan solar cell's on earth?
If they were on earth, at least, you don't have to launch them, you don't have to defend them furiously against space-debree, no fancy microwave power-transfer device,... (make up more yourselves).
Evolution (as we know it) is set out of effect in the "rich" parts of
... are
the world, where medicine and social security now are much more
important than traditional evolutionary "virtues" like strength, resilience
and other stuff like that.
Many rich countries help those of their inhabitants unable to
reproduce themselves via various medical techniques, people who are
sick are personally cured by medicine, allowing them to breed
offspring that is more susceptible to disease.
This is altering the forces which evolution operate under to be more
about money and knowing good doctors,... , than about genetically transferred individual
abilities to survive.
To some extent these values: money and good doctors,
individually transferable, via heritage and social bonds (family), and
thus somewhat relate to genes.
We may just see another kind of evolution, based much more on social
position, than on genetically transferred capabilities, making an
impact over the next 50-100 years.
I'm not saying this is the way I would like it to be, just that might
be possible.
As I don't have much actual knowledge in these fields, don't take the
predictions to serious, but I wanted to share them anyway, so that I
can discuss them and learn.
A lot of the posts here are angry at Nick Moffitt for doing what he does. But I side with him:
If you wan't to be part of something he does, you have to play by his rules. I can't see anything wrong with that. If you wan't to use Outlook you have to sign an agreeement, even if you link with GPL code you have to "play by the rules"...
Evolution will decide what good/harm he does, and there's nothing you can (or should) do about it, except act according to your beliefs.
Let nature take it's course.
Many of the comments in this discussion states that it's hard to write a portable and yet well-performing compiler, as an argument defending GCC.
There simply no substance to that argument. Any optimization you can do in a target-specific compiler can be done in a portable compiler, simply by only performing it when it's known to be valid.
It's not "harder" to optimize in a portable compiler, but there's a lot more targets to cover, and thus much more work to be done. And I think that's probably the actual problem that GCC has, compared to Intel.
BTW: I'm no GCC-fan, but I like it for it's (relative, compared to Borland, MSVC and Sun compilers) C++ standards confomance, and for the best error-messages (call/inclusion tracking for templates/headers).
But a relation cannot be reflexive and anti-symmetric at the same time:
We can't have that.
Although I like to apply complexity theory to stuff as much as anyone, it doesn't really make sense here:
Quote, The article, Abtract, line 5:if it is accepted that algorithmic complexity is an appropriate
definition of the complexity of a programming project
This assumption set's focus in the wrong place. Most projects have low algorithmic complexity and many of those fail. so that's not the actual problem.
It might become a problem when people in the software world start solving hard (algorithmic complexity-hard) problems -- but I don't see that happening in commercial mainstream software within my lifetime ;)
Please explain to me how an estimate without a bound on the accuracy of the estimate is anything but a guess?
To make any kind of sense, the "==" relation would have to be transetive, since his arguments about what "confused" him used that property.
;)
It's probably also reflective, since an extrinsic definition of equality (the one used in the relation) should be a sub-relation of the intrinsic equality, that is the one we use to compare elements in our universe (in this case the language). And we prefer any string "Linux" to mean the same as any other string "Linux".
I don't see him using the (normally usefull) symmetry property, which would make == an equlity relation, so I cannot assume that's a property of the relation... it may be, nobody knows,.... he has not defined the relation, which is what leads him into trouble in the first place... and me into laughing
Your statement has nothing whatsover to do with a new "branch" of logic, and can be treated in ordinary first-order logic.
Every time some under-graduate starts algebra or logic courses, this idea (A != A) or (A -> !A) or something like that arise, and in some cases the student even understands why it's funny, and learns from it. Well let's hold hands as we look at it:
Let us work in the universe U with at-least one element, and no upper bound to the number of elements
The interpretation of the axiom "A != A" is: "no intrensicly equal values are extrensicly equal", since it is shorthand for the axiom:
- forall x in U: x != x
Where two elements in U are compared with "U"'s equality relation (lats call that =A), and the statement "x != x" is evaluated in the relevant logic's definition of "!=" (lets call that !=B).Normally the definition of "!=" is formulated in terms of the equality defined by U:
Which very nicely make extrinsic and intrinsic equality the same relation, provided that the used logic is poverfull enough ( in other terms, extrinsic equality is a sub-relation of intrinsic equality)
So the statement (A != A) claims that the logic can distinguish between to instanses of the same element from U, which is utter rubbish!
This statement will of-course convince noone (at least if the are pedantic, and thus good students ;), so let's take the usual Heidelberg Propositional Logic (Let's call that Hprop) and extend it with axiom "A != A" (call that Hprop') and prove that Hprop' is not sound.
Let x be any element in U. By equality and confounding axioms and the axiom of "&&" we have:
So Hprop' proves
But:
So via the deduction lemma, we have shown that Hprop' proves false.
Let us note, that Hprop is sound and comlete, and therefore no sound first-order logic can contain the axiom "(A != A)".
Just because he chooses to name his relation "==" does not mean it's an equivalence relation (reflexive, transetive, symmetric).
In both our posts, only the transetivity is used, not symmetry.
It's obvious (by your own argument) that he does not consider "==" to be symmetric.
Since already the 2 statements:
Prove that (since == is transetive):
And it's a generally accepted axiom that:
When we apply the usual axiom of negation:
We get:
We can now invoke the usual definition of && to prove:
Establishing that your proof-system is not sound and thus you should expect it to be confusing, since it can prove any statement what-so-ever.
I suspect, that if you remove the "transetive" property from your definition of "==" your system may become sound, but unfortunatly not as funny.
Logic is not easy, but it's good clean fun
I thought of patenting writing a patent application ;)
Actually, the motivation for the comment was another. Look at: http://slashdot.org/comments.pl?sid=21777&cid=2375 669
When one wishes to illustrate a missing point in a question, it's commonly known as rethorical trick to rephrase the answer as a "Counter-question" which will help "the other guy" see problems in the question.
This rhetoric is related to the rhetoric of analogy, allowing you to "reason" about something without explicitly mentioning your arguments (which would be a long story about the value of Open-Source and stuff).
The original question was (stated in the post) posed in a way that could be understood something along the line of "Well, if linux is so good, then point me to a place where they use it (seriously)", implying a lack of value to the "linux product".
Since WinMe is not installed in corporate environt, chances are you will not be able to think of a "large installment" of WinME. But the person who posed the question will most likely hold that WinME has value! The "poser" of the question will now not be able to make the argument : "no large installment implies poor value" (without implicating WinME == poor value).
Most of the time, discussions are not based on presenting arguments, but on pushing rhetoric against non-believers -- this is a tactic many people use when they don't agree with the other part of the discussion (Just look at GPL zealots vs. M$ zealots).
Where is the largest installment of WinME?
(Not counting the producer, Microsoft -- of course).
--
Helge Jensen
Sometimes, when people have their noses in notes all day, it's because the blody thing doesn't work at all, or in some mysterious way.
--
Helge Jensen
But are we ready? We know surprisingly little about the social and psychological impact of e-mail, beyond usage, volume and demographics.
Well, this should come as no surprise. The human race has a habit of not "being ready" for it's inventions. I actually suspect that's what progress is all about ;)
Why does everyone (especially in the Open Source community) try to force Gnu/Linux into the dominating place for OS'es?
Unix OS'es have limited application, because of their close relation to POSIX. I.e the usage of Linux (the kernel) in embedded systems is extreme bloat (although the nerd in me would like that linux-wrist-watch).
When will people realize, that an OS is like any other tool, and you should select the right tool for the job, not the same bloated tool all the time.
I can't remember when I last saw so many flame-bait and troll articles moderated to "interesting" or "insightfull.
Please take time to Meta-Moderate today!
Flerbage: I have the condition of flerbage when I can behave in the confidence that nobody will take my life, my physical property, or my time without my consent.
Make up any posistion, what so ever on copyrights, programs and freedom.
If you follow the rules according to that position, your (so-called) "flerbage" will not be affected in any way, what, at all.
So, you don't want to test what maximizes "flerbage", it's simply misleading to even enter that definition into the convesation.
What you really wan't to do, is list the requirements of the interested cotegories:
Helps "Use" the software
Helps pay bills
No two people work alike
Software should "just work", like lights and phones
Share producst from different software producers
Dont do work that others aready did
Ability to control your creation
Allows you to make monty
A wealthy country is a healthy country
Another term in power please!
At least in the US, they paid the campaign
Now all you have to do, is keep adding things to the list and maximize the "happiness". No wonder there are so many conflicting solutions to an equation without a single maximum in all the dimensions.
Proposition 1:The number of times your web-server is attacked is a compositional function of the log entries.
What prop. 1 tells you is, that to you may directly apply the "divide and conquer" strategy to the problem, analysing parts of the log-file seperatly and composing the application of your counting function to each part by the binary operator "+".
This tells you, that once you have visited a part of the log-file, you will never have to visit that again, so maybe your program should look something like:
Of course, you need to look out for synchronization in this version of the program, but it won't grind your server to a halt when 3-4 people press the "Number of code-red worms deflected" link at the same time