comp.lang.c++@googlegroups.com | Google Groups | ![]() |
Unsure why you received this message? You previously subscribed to digests from this group, but we haven't been sending them for a while. We fixed that, but if you don't want to get these messages, send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
- Announcement of new C++11 library to handle measures - 17 Updates
- knock knock: my self-documenting code pursuit - 8 Updates
c.milanesi.bg@gmail.com: Oct 05 02:24AM -0700 Ronald Landheer-Cieslak wrote: > now and while I've worked with micro-controllers that required very small > footprints, by far most devices I've seen had quite powerful processors, > and all could be programmed in C++. I think that small micro-controllers, that is computers that address no more than 64 KB of code, are still used, and that for that C++ language is not actually used and should not be actually used. Though, now most micro-controllers are not so small, and for them C++ should be used, and a units-of-measurement library should be used. C++ is evolved since 2011, and I think that for successful processors C++ compilers have evolved or will evolve accordingly. Therefore, I think that requiring C++11 compliance should not exclude too many C++ programmers in forthcoming years. > upholds the "zero overhead" principle: if behind the scenes a "Volt" is > simply a float (or a double), it should take no more place than that float > and should be no more costly to work with. I did that: sizeof (vect1<radians,float>) == 4; > Ideally, it would also know, at > compile-time, that Volts multiplied by Amperes give a Watts, and that it > doesn't make sense to add them; After having defined DEFINE_MAGNITUDE(ElectricPotential, volts, " V") DEFINE_MAGNITUDE(ElectricCurrent, amperes, " A") DEFINE_MAGNITUDE(Power, watts, " W") DEFINE_DERIVED_MAGNITUDE_SCALAR_SCALAR(ElectricPotential, ElectricCurrent, Power) This statement cout << vect1<volts>(3) * vect1<amperes>(4) << endl; outputs "12 W", and this statement generates a compilation error cout << vect1<volts>(3) + vect1<amperes>(4) << endl; > that a dimensionless value divided by > seconds would give Hertz, etc., with compile-time checks for the operations > that make sense and no run-time overhead. After having defined DEFINE_MAGNITUDE(Unitless, units, " u.") DEFINE_MAGNITUDE(Time, seconds, " s") DEFINE_MAGNITUDE(Frequency, hertz, " Hz") DEFINE_DERIVED_MAGNITUDE_SCALAR_SCALAR(Time, Frequency, Unitless) this statement cout << vect1<units>(10) / vect1<seconds>(2) << endl; outputs "5 Hz". -- Carlo Milanesi |
Wouter van Ooijen <wouter@voti.nl>: Oct 05 12:03PM +0200 > language is not actually used and should not be actually used. > Though, now most micro-controllers are not so small, and for them > C++ should be used, and a units-of-measurement library should be used. Your 'that address no more than 64 Kb of code' is a bit ambiguous: there are small 32-bit uc chips that can *address* 2^32 bytes of code (minus some RAM and peripherals) but *contain* only a few Kb of Flash. For such chips C++ is perfect, provided that it is used in an appropriate way. |
c.milanesi.bg@gmail.com: Oct 05 03:10AM -0700 Il giorno sabato 4 ottobre 2014 02:05:21 UTC+2, Luca Risolia ha scritto: > via literal operators, for example: > using namespace measures::si; > auto length = 10_m; // 10 meters (relative measure) I don't think it would be good, for the following reasons: * User-defined operators are still not supported by the widely-used Visual C++ compiler, and perhaps by other compilers. * There are actually 4 kinds of one-dimension measures (without considering angles): static relative, dynamic relative, static absolute, dynamic absolute. * A measure can have a programmer-defined underlying numeric type (float, double, ...). * There are many SI units, and some of them may use a symbol the programmer wants to use for another purpose. * SI is used a lot, but many non-SI units are still used, and that would open requirements for every unit used on Earth at some time. What may be reasonable is includeing in the library the following macros: #define DEFINE_VECT_STATIC_UNIT_OPERATOR(Unit, Num, Operator) \ vect1<Unit,Num> operator "" _##Operator(long double n)\ { return vect1<Unit,Num>(n); } #define DEFINE_POINT_STATIC_UNIT_OPERATOR(Unit, Num, Operator) \ point1<Unit,Num> operator "" _##Operator(long double n)\ { return point1<Unit,Num>(n); } #define DEFINE_VECT_DYNAMIC_UNIT_OPERATOR(Unit, Num, Operator) \ dyn_vect1<Unit,Num> operator "" _##Operator(long double n)\ { return dyn_vect1<Unit,Num>(n); } #define DEFINE_POINT_DYNAMIC_UNIT_OPERATOR(Unit, Num, Operator) \ dyn_point1<Unit,Num> operator "" _##Operator(long double n)\ { return dyn_point1<Unit,Num>(n); } after which the application programmer may write the following statements DEFINE_MAGNITUDE(Space, meters, " m") DEFINE_VECT_STATIC_UNIT_OPERATOR(meters, double, m) after which he/she may write the following statement auto len = 10.0_m; -- Carlo Milanesi |
c.milanesi.bg@gmail.com: Oct 05 03:41AM -0700 Wouter van Ooijen ha scritto: > some RAM and peripherals) but *contain* only a few Kb of Flash. > For such chips C++ is perfect, provided that it is used in an > appropriate way. I have no experience with using C++ for systems containing only few KB of memory. And I am in no place to get such experience. I let other to evaluate feasibility of using C++ compiler and libraries on such system. For myself, I think that portability on micro-controllers is not a good-enough argument to avoid the use of the "decltype" keyword. May be another problem is the fact that the library includes the standard header <unordered_map> to create 4 small hash-tables used only by dynamic measures. If that is a problem, it may be possible to implement the hash-table code inside the library, or remove dynamic measures by a conditional compilation. -- Carlo Milanesi |
c.milanesi.bg@gmail.com: Oct 05 04:14AM -0700 Öö Tiib wrote: > > I accept suggestions for a renaming. > What I suggested is to use "relative measure" or "relative > quantity" typed out literally. I will take that into account. > with engines pulling around objects that are attached to > each other in real or emulated world (IOW scientific and > engineering applications). My mileage (that is in CAD-CAM applications) is that engineering software uses a lot multi-dimensional quantities, typically as positions or movements in a plane or in space; but probably you are right that for scalar magnitudes, like time and temperature, and for those who work only with one-dimensional quantities, it is weird to emphasize that these quantities have only one dimension. -- Carlo Milanesi |
"Öö Tiib" <ootiib@hot.ee>: Oct 05 05:06AM -0700 > KB of memory. And I am in no place to get such experience. > I let other to evaluate feasibility of using C++ compiler and > libraries on such system. Relax, it is fine. The C++ language is efficient to edge when used correctly. To the same edge that C targets. C++ libraries are mostly templates and header-only. We only get what we actually use from library and from that only the part that compiler could not do compile-time. > For myself, I think that portability on micro-controllers is not > a good-enough argument to avoid the use of the "decltype" keyword. Forget thinking "micro-controllers". I bet your TV-set if you have one (I don't) runs Linux somewhere inside of it. It is not 1966 anymore. That is OK that you want to use C++11 features, these are cool, just that you did put it up as some sort of first benefit when comparing to Boost while in real industry it is usually painful impediment. If I would write such a library I would also want to use 'auto', constexpr, variadic templates and 'static_assert' besides that 'decltype' from C++11. These things help a lot when I want to deal with or to detect or to give diagnostics about usage of lot of types in mix at compile-time. Boost contains some hacky workarounds and poor man substitutes that can be used conditionally when real language features are not available and that is actually large benefit of Boost. > used only by dynamic measures. If that is a problem, it may be > possible to implement the hash-table code inside the library, > or remove dynamic measures by a conditional compilation. I imagine such dimensioned type system as static and nothing of it feels dynamically polymorphic. So I can't imagine need for virtual functions or hash tables or maps of function pointers. Can you elaborate what is the purpose and use cases supported by your dynamic unordered map? |
c.milanesi.bg@gmail.com: Oct 05 05:45AM -0700 Öö Tiib wrote: > templates and header-only. > We only get what we actually use from library and from that only the > part that compiler could not do compile-time. But if I use a non-empty standard container (like "vector" or "unordered_map"), a memory allocator and an exception handler are included to my executable. For some application that is not desirable. > > a good-enough argument to avoid the use of the "decltype" keyword. > Forget thinking "micro-controllers". I bet your TV-set if you have > one (I don't) runs Linux somewhere inside of it. But then it uses more that few KB of RAM. > cool, just that you did put it up as some sort of first benefit > when comparing to Boost while in real industry it is usually > painful impediment. Well, I presented it as a difference. It is a benefit for Boost. > Boost contains some hacky workarounds and poor man substitutes > that can be used conditionally when real language features are not > available and that is actually large benefit of Boost. I cannot imagine how to to the following with C++98. typename <typename T1, typename T2, typename T3> T3 add(T1 a1, T2 a2) { return a1 + a2; } Given that T1, T2, and T3 are floating-point number types, which is the type of T3? Using C++11 I can write typename <typename T1, typename T2> decltype(T1()+T2()) add(T1 a1, T2 a2) { return a1 + a2; } > functions or hash tables or maps of function pointers. > Can you elaborate what is the purpose and use cases supported by > your dynamic unordered map? My library supports two kinds of measures, for different purposes: * Measures with statically-defined unit, to be used when the application programmer knows which unit to use for a variable. * Measures with dynamically-defined unit, not so efficient, to be when the programmer knows which magnitude to use for a variable, and knows also a set of possible units to use for it, but the actual unit is defined only at run-time as it depends on input data or on system configuration. In the latter case, some lookup tables are used for the following purpose. When two measures are multiplied, say a force is multiplied by a length, the unit of the resulting measure must be chosen among the available units for energy. And as the units of force and of length are dynamic, i.e. stored in variables, the unit of energy cannot be computed at compile-time, but looking it up in a container. -- Carlo Milanesi |
"Öö Tiib" <ootiib@hot.ee>: Oct 05 05:48AM -0700 > My mileage (that is in CAD-CAM applications) is that engineering > software uses a lot multi-dimensional quantities, typically as > positions or movements in a plane or in space; ... Yes and my point was that those multi-dimensionally meaningful spins, growths, velocities and skews are typically feed into linear algebra library. Upside of linear algebra libraries is that those do large amounts of calculations rather efficiently and close to optimally. That makes it unlikely that you can compete with those. Downside of such libraries is that those leave meaningfulness of such calculations up to user so matrix of doubles multiplied by matrix of doubles is a matrix of doubles. So my suggestion was to cooperate and to interface with such libraries for all that math rather than try to have the vectors and matrixes and linear algebra reinvented inside of your library. > like time and temperature, and for those who work only with > one-dimensional quantities, it is weird to emphasize that > these quantities have only one dimension. That was only minor nit really about naming that you brought up yourself. People can put up with such quirks and if they don't like it they can hide it away with aliases either way. Major goal is to provide value and convenience without hindering efficiency ... all semantic issues are secondary. |
Luca Risolia <luca.risolia@linux-projects.org>: Oct 05 04:15PM +0200 > I don't think it would be good, for the following reasons: > * User-defined operators are still not supported by the widely-used Visual C++ compiler, and perhaps by other compilers. I don't know what other compilers you are considering, but both GCC and CLANG have been supporting literal operators for quite a while now and are certainly widely-used and ready for the C++11 era. > * There are actually 4 kinds of one-dimension measures (without considering angles): static relative, dynamic relative, static absolute, dynamic absolute. Yes, with regard to SI units I was talking about, then choose the appropriate type. According to the definitions you wrote in your tutorial, I would expect "auto len = 10_m" to unambiguously refer to a "static relative" measure, while for a temperature "auto t = 10_K", I'd expect a "static absolute" measure. > * A measure can have a programmer-defined underlying numeric type (float, double, ...). I don't see where is the problem. I'd expect the underlying numeric type to be either integral or floating point, according to what I specify as operator argument. unsigned long long and long double are the two numeric parameter types allowed by literal operators, so you can use them if you cannot find reasonable defaults: vect1<..., unsigned long long> len = 10_m; // integer literal (ULL) vect1<..., long double> len = 10.0_m; // floating point literal (long double) (if your library supports (or not) operations between measures having different underlying numeric types is another matter). > * There are many SI units, and some of them may use a symbol the programmer wants to use for another purpose. There are 7 *base* units in the SI (with well defined names and symbols). I would not say they are so "many". As I deliberately wrote in my example, you can probably make the SI symbols available under a specific namespace if you wonder about possible collisions. > * SI is used a lot, but many non-SI units are still used, and that would open requirements for every unit used on Earth at some time. True, but IMHO SI is a special case and should be included in the library from the beginning. |
Luca Risolia <luca.risolia@linux-projects.org>: Oct 05 05:14PM +0200 > is more understandable than the former one. > But as my library is still in development, > I accept suggestions for a renaming. To make the things more readable, I suggest that you also provide one factory for all the points and one factory for all the vect's, which return the right type according to the number of passed arguments, for example; auto x = make_vect<meters>(0, 0); // vect2 auto y = make_vect<meters>(0, 0, 0); // vect3 auto p = make_point<meters>(0, 0); // point2 auto q = make_point<meters>(0, 0, 0); // point3 |
"Öö Tiib" <ootiib@hot.ee>: Oct 05 08:38AM -0700 > T3 add(T1 a1, T2 a2) { return a1 + a2; } > Given that T1, T2, and T3 are floating-point number types, which is > the type of T3? Impossible in C++98 but Boost uses pre-C++11 extensions that majority of compilers had (like 'typeof' or '__typeof'). > Using C++11 I can write > typename <typename T1, typename T2> > decltype(T1()+T2()) add(T1 a1, T2 a2) { return a1 + a2; } Yes. C++11 resolved lot of things that were sloppy in C++98/C++03. > and knows also a set of possible units to use for it, but the actual > unit is defined only at run-time as it depends on input data or on > system configuration. Ok, let me try to think about it. 1) Most efficient is to use the values with fixed units that involve least amount of conversions done during math. 2) However user may want to see or to enter milliseconds or minutes instead of seconds or something like that. 3) Also users differ so there is always controversy. A solution: We let user to dynamically pick a variable (lets say to pick an index of member of tuple or variant) that has unit that he wants to use during I/O and assign our internal variables to or from it. However that user-picked member can fully have fixed unit and still it can be used for I/O. So a need for dynamic units does not follow only need for dynamic choice between different variables. > units for energy. And as the units of force and of length are dynamic, > i.e. stored in variables, the unit of energy cannot be computed at > compile-time, but looking it up in a container. Using variables with such dynamic types in math feels inefficient since there are likely (dynamically decided) conversions needed on the fly. Especially when there is a lot of math to do it hurts. It is less crucial in I/O. In I/O the throughput and latency are the bottle-necks. Modern processors are idle most of the time during I/O so can use the spare time to convert things and what not. That is why most web services are Java, C# or even PHP. Only most huge sites like youtube or google use C++. I suggest you consider there a bit ... might be that you can get rid of needless dynamic units or might be you can move them to I/O layer or might be that you have some more reasons why these are needed in math. |
Ronald <rlc@vlinder.ca>: Oct 05 04:23PM > I think that small micro-controllers, that is computers that address no > more than 64 KB of code, are still used, and that for that C++ language > is not actually used and should not be actually used. [putting flamethrower away] Let's agree to disagree, shall we? <snip> > this statement > cout << vect1<units>(10) / vect1<seconds>(2) << endl; > outputs "5 Hz". That looks nice! I'm assuming you'd have some "using namespace"s to make this actually work? Also, when compiled, there's no difference between a volt * amperes and a float * float? I'll go take a look :) rlc |
Wouter van Ooijen <wouter@voti.nl>: Oct 05 06:44PM +0200 嘱 Tiib schreef op 05-Oct-14 5:38 PM: > of needless dynamic units or might be you can move them to I/O layer > or might be that you have some more reasons why these are needed > in math. But as far as I understand, as a user, those dynamic units cost me nothing when I don't use them. If that is correct the cost of having them is small (= skipping the (ir)relevant parts of the documentation), so even a rare use case for them might be enough for them to be worthwhile. |
c.milanesi.bg@gmail.com: Oct 05 10:41AM -0700 Ronald Landheer-Cieslak wrote: > > outputs "5 Hz". > That looks nice! > I'm assuming you'd have some "using namespace"s to make this actually work? To work, it needs also the following statements: #include <measures_io.hpp> using namespace measures; using namespace std; > Also, when compiled, there's no difference between a volt * amperes and a > float * float? vect1<volt,float> * vect1<ampere,float> should generate the same machine code than float * float, but only if compiled with optimization on. I didn't check machine code, but run times are the same. vect1<volt> * vect1<ampere> is equivalent to double * double > I'll go take a look :) Then I suggest you to start from the Tutorial, and not try to build the tests. -- Carlo Milanesi |
Geoff <geoff@invalid.invalid>: Oct 05 12:32PM -0700 On Sun, 5 Oct 2014 02:24:50 -0700 (PDT), c.milanesi.bg@gmail.com wrote: >outputs "12 W", >and this statement generates a compilation error > cout << vect1<volts>(3) + vect1<amperes>(4) << endl; Speaking as an Electronic/Electrical engineer of some 38 years in practice: Volts * Amps is Watts only if both values are scalar. (e.g., It's a DC circuit or it's an AC circuit with no reactive components.) Volts * Amps is always VA in reactive AC circuits when the values are scalar. (i.e., you only know the magnitudes of the vectors and not the angles.) Power plant operators only speak of Mega-VARs when talking about generating capacity, seldom Watts. A 2000MW hydro-electric plant would actually be producing some 2500 MVARs at PF=0.8, a very real difference. In DC circuits VA is Watts but only used when the context is known. If Volts and Amps and the power factor (PF) are known then Watts = Volts * Amps * PF when they are all scalar. If Volts and Amps are vectors, only then can you compute Watts directly. A proper class to handle these computations would convert scalars to vectors of the form v = x + iy where iy is zero. Then it would display Watts if the product had a zero imaginary component and VA if not. I downloaded your source but I have not been able to successfully compile it. |
"Öö Tiib" <ootiib@hot.ee>: Oct 05 12:40PM -0700 On Sunday, 5 October 2014 19:44:45 UTC+3, Wouter van Ooijen wrote: > them is small (= skipping the (ir)relevant parts of the documentation), > so even a rare use case for them might be enough for them to be > worthwhile. AFAIK all compilers are in difficulty to optimize out any sort of dynamic polymorphism even if it is not used. If the efficiency drop is of any significance then it may be is an unneeded choice that will be made one way as rule by experienced users. Author has still to maintain code and documentation (useless work). So better idea is to consider it beforehand. |
Christian Gollwitzer <auriocus@gmx.de>: Oct 05 10:21PM +0200 Am 01.10.14 21:11, schrieb Wouter van Ooijen: > For me (but note again that I am not a native english speaker) "don't > really kown' and "really don't know" are close, but I might be totally > wrong here. To me (also non-native), there is a big difference: "I really don't know" means "I have no clue", "never heard of", whereas "I don't really know Boost.Units" is "I am no expert in Boost.Units (but know it and may have used it)". The latter might also be modesty. Christian |
"Charles J. Daniels" <chajadan@gmail.com>: Oct 04 04:45PM -0700 On Saturday, October 4, 2014 2:01:26 PM UTC-7, Öö Tiib wrote: > > more meaningful, a la "self documenting code". I'm enjoying it. > It is most important ... that you yourself enjoy it. I certainly agree =) > most of the time value 'whosthere.length()-1'. That is because > 'some_string.find(other_string)' returns most of the time > 'string::npos' (that is required to be 'SIZE_MAX'). I see your point about what happens when whosThere is not found. The coder is not given the luxury of assuming a find occurs with this construct. The example has the luxury of knowing a find occurs in the case given, so it focuses on the effect of After. In my personal code, I only use After starting from a valid position (not npos), and additionally, I only ever pass After a string that literally represents what is sitting at that starting position. > Since example of its usage was broken I suspect that it is not good > idea to use it. Same with your other function whose example does not > even compile for that 'lastPosition'. I added a note about "lastPosition" to my original post. My custom string class, which is a std::basic_string, exposes a lastPosition() -- but I now realize since After is generic to basic_strings and not specific to my custom strings, I should genericize the example. Thanks =) > Aliasing lengthy constructs is often good idea but purpose of > aliasing 'str.size()' with 'After(str)' and 'str.size()-1' with > 'Through(str)' is confusing for me. The thing I find appealing about them is that, from a starting position that contains str, After makes it clear the result position is the character that follows, and Through, as I interpret the word, is up to the very end but not beyond. So After and Through make it entirely clear which position I'm advancing to, in english words. I have another function span() that may make it more clear what I like about this kind of construct. string src("Grab the fifth word from here."); int startPos = 15; int endPos = 18; string fifthWordNormal(src, startPos, endPos - startPos + 1); string fifthWordMeaningful(src, startPos, span(startPos, endPos)); Span, which I won't make explicit, just means the inclusive length, but without this span concept, notice I have to add 1 in fifthWordNormal. What I'm saying is that in my code, in so many places these little changes, +1 or -1, happen or don't happen, and for a million different reasons, such that in each case, I have to repetitively do mental processing to make sure my indexes all make sense for the purpose at hand. With fifhWordMeaningful above and span, I just have to make sure my positions are valid, but then span keeps me from every having to point to my fingers, assign the 0 index to my thumb, and make sure I'm not one off somehow. It's clear, it's quick, and I can trust it. =) If After, Through, span, and others take root in my general vocabulary, they answer a lot of questions right up front, just like we already benefit from when using things like iterators that setup clear boundaries. > some pointer, iterator or position math may be complex > to read. I add either comment or move the whole arithmetic > to separate little function. So then you see my point. Arithmetic upon an index position often becomes abstract. My goal is make the why of the operation explict (After, Through), and hide the various incantations of +1 -1, behind that call. Rather than seeing +1 or -1 and then trying to figure out if I was doing a Through or an After, which is the type of code rediscovery thing I'm all to used to doing. |
"Charles J. Daniels" <chajadan@gmail.com>: Oct 04 05:33PM -0700 On Saturday, October 4, 2014 4:17:13 PM UTC-7, Mr Flibble wrote: > then what you think is a good name others might think is just > non-standard noise. > /Flibble I absolute see your point, but 1) I have the luxury to be talking about my own personal code that others need not see, and that I don't require assistance with. So if writing it in Chinese helps me, I don't have to worry about the standard library, standard anything, or intelligibility to others. I do agree std::max is perfect for the max Choose scenario above, and I do agree it's the superior solution -- it's explicit and compact, just what I most prefer. Hard to make code scream better than std::max! Unfortunate example in that respect. Choose is meant to be explicit about the sourcing of the variable, "a choice between two options", but is generic to the how. It keeps me from having if-else branches than I later re-understand to be making such a choice. My current line of thinking is that, I use if-else for many reasons, but if I make explicit the contextual basis/purpose for an if-else, I won't need to digest the branches to glean that information. Choose can also serve to make code compact, which to me is a help to readability so long as it's not information dense. I have a ChooseOp which is indentical to Choose in it's implementation, whose only purpose is to prime the reader to look for a chained call operator: char properCase = ChooseOp(towupper, towlower, conditionOrFunctor)(inputChar); I'm looking to rename ChooseOp, because the name implies an operation is chosen, but the true intent in my mind is to prepare myself for a chained call to an operation. It's a step up from char properCase = Choose(towupper, towlower, conditionOrFunctor)(inputChar); which looks like a normal Choose but then switches it up on you by inserting an expecting feature to the a place you might not look. If I could usefully call ChooseOp something like "ChooseResultFromAChainedFunctionCallFromOperationChoice" I'd be happy. But just know Mr Flibble, even I have my limits. I'm goal oriented with all of this. Any construct I use should somehow be more explicit and readily incorporated by a ~familiar~ user. The standard library requires familiarity to be incorporated so easily, as no doubt you understand. Again, in my own personal "no one else needs to be able to read it" code, I again agree std::max is the best in the original scenario, to make my intentions for my code explicit. =) Here, explicit will have get me targeted feedback to my purpose =) Knowing my code has problems with foreignness to others is rather essential, and you brought that up right away. |
"Öö Tiib" <ootiib@hot.ee>: Oct 04 07:04PM -0700 On Sunday, 5 October 2014 02:45:45 UTC+3, Charles J. Daniels wrote: > I only use After starting from a valid position (not npos), and > additionally, I only ever pass After a string that literally represents > what is sitting at that starting position. That constrains valid usage of 'After' into narrow context and then it feels more reasonable to have functions that implement the narrow case itself and enforce the constraints too: string substr_after(string from, string other) { string::size_type p = from.find(other); // enforce constraints: if (p == string::npos) { throw "bad parameters"; } p += other.size(); return from.substr(p); } > is the character that follows, and Through, as I interpret the word, > is up to the very end but not beyond. So After and Through make it > entirely clear which position I'm advancing to, in english words. Might be, for me neither name indicates returning a position in string. > int endPos = 18; > string fifthWordNormal(src, startPos, endPos - startPos + 1); > string fifthWordMeaningful(src, startPos, span(startPos, endPos)); I have overcame that problem by accepting that "end" means "one past last" in C++. Similarly as "first"/"start"/"begin" is at position 0 in C++ (not at 1). So 'endPos = 18' is wrong in mine code; it should be '19' (or if it is '18' it should be called "lastPos" or "backPos" that I rarely use). Btw: what you extract looks like fourth word not fifth. ;) > that call. Rather than seeing +1 or -1 and then trying to figure out > if I was doing a Through or an After, which is the type of code > rediscovery thing I'm all to used to doing. Yes I see your point, but for me "end" is same as your "After" and if positions "begin" from zero the "size" or "length" gives me position of "end". I use "end" mostly since I need the position of "last" or "back" very rarely for anything. As result I rarely have those +1 or -1 in my code. Additional benefit is that empty sequence is where "start" and "end" are equal but "last" or "back" is logic error in empty sequence. Your 'Through' returns 'string::npos' to empty string. |
"Charles J. Daniels" <chajadan@gmail.com>: Oct 04 10:01PM -0700 On Saturday, October 4, 2014 7:05:10 PM UTC-7, Öö Tiib wrote: > p += other.size(); > return from.substr(p); > } I agree there is certainly said to be said for enforcing constraints, but so far I don't see the need given the intend use of After and Through. I only use these in a context where I have the constraints met in the first place, so for anyway. > Might be, for me neither name indicates returning a position in > string. I understand. The way I see After and Through is as a part of a standard "positions" library. So I'll get very used to them, just like wstring::npos, std::endl, etc. Those mean very little, but we toss them around with accustomed ease. The names After and Through aren't the perfect ideal names to me either, but they are one word English words, so they're good enough for me. After used to be Beyond, but that has too strong an implication of well after, and not just after. After could be called Past, PositionBeyond, or whatever. If anyone were to want to do the same thing, they could certainly substitute names that translate move vividly to them. > in mine code; it should be '19' (or if it is '18' it should > be called "lastPos" or "backPos" that I rarely use). > Btw: what you extract looks like fourth word not fifth. ;) Yes, funny, I did pull the 4th word :-p I haven't taken a generalized meaning of "end" as one past, except in the context of an iterator. My positions "library" doesn't interpret to me conceptually like iterators, it's just arithmetic of indexes in my perception. > position of "end". I use "end" mostly since I need the position of > "last" or "back" very rarely for anything. As result I rarely have > those +1 or -1 in my code. I get a decent amount of them. And like I said I always have to mentally run through my indexing to make sure it's right, even if there is no +1 or -1 because I don't have clear expectations that I know for sure apply in the multitudinous situations they come up in. > is where "start" and "end" are equal but "last" or "back" is logic > error in empty sequence. Your 'Through' returns 'string::npos' to > empty string. Through, while not very clearly documented to this effect, is literally expecting to be used when you are on the starting position of some specific value within a string, so you wouldn't pass it an empty string or you wouldn't be on a valid position in the first place. You can go through the end of the fourth/fifth word if you're not at it's starting position. Through to me is a very very context sensitive choice, and in that context Through makes my intent, ~and~ the result, very clear, and valid. Keeps me from having to off-by-one-validate over and over as I tend to my code -- is the goal anyway. I just wrote the things last night. I've been using other "meaningful" constructs longer, and I tend to like them. In fact, recently my code has been becoming quite a piece of art to me: clean, obvious, direct, transparent, uncluttered. Pretty crazy. It's certainly the goal I've been working on. You know, some people balk at even using meaningful variable names, or fume at the suggestion to abbreviate less :-p |
"Charles J. Daniels" <chajadan@gmail.com>: Oct 04 10:04PM -0700 > I have a handful of "meaningfulness" constructs around now. I was documenting one after being up all time, and tickled myself, twice! And just to be specific, my original intention was to share the humor of my examples :-p The got me laughing so hard I just had to post. See that "being up all time" comment up there, I meant be up all night, but it's why I couldn't type. :-p The feedback is much appreciated though, certainly. |
Dombo <dombo@disposable.invalid>: Oct 05 03:01PM +0200 Op 05-Oct-14 0:20, Rick C. Hodgin schreef: > else to make it happen. He's reaching out with both arms to draw > you to His free offer. He is ready, willing, and able to receive > you. The idea that life comes to an end is much more appealing to me than worshiping god for eternity. > that which you will then experience for the first time. It is > more profound than any thing which has come to you at any point > prior in your life. You are more likely to find peace if you give up religion. Religion is is the source of war and unjustified fears standing in the way of wellbeing of humans and animals far too often. > grateful that you did. > Best regards, > Rick C. Hodgin You make a lot of assertions but provide zero proof to support those assertions. Insisting that others should believe what you are saying just because you say so is rather arrogant. Given the reasoning displayed by the christian nutcases in this newsgroup I'm inclined to believe that software engineering is not for them and that they and the world would be better of doing something else. |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Oct 05 09:14AM -0700 Dombo wrote: > Insisting that others should believe what you > are saying just because you say so is rather > arrogant. I ask you to see for yourself. I testify to what I have experienced. For each person they too will come to Him, being drawn to do so from within. Everybody who is perishing will never do so, for if they did they too would be saved. Taste and see for yourself, Dombo. All Jesus offers is total forgiveness for your sins, and eternal life in a way whereby we are restored to God. No more sin. No evil. No hate. No pain. This is what Jesus offers. It is free, and it is extended to everyone. All who come to Him will be saved. Everyone else will perish. And since He extends the offer to everyone, only those who blatantly, and purposefully reject His free offer, reject Him (reject Truth, and all that is good, right, true, lovely), will enter into Hell. It will be each person who condemns their fate. My posts are to teach you what awaits. You, and all of us, are already there. The only way to be saved is to come out, and the only way to come out from this fate is through the One with the power and authority to take away your sin. Jesus is the only way. You are right that religion has caused much death, much pain, wars, hate, etc. Jesus is not religion. He is a living Savior, and His followers are not religious, they have been born again of His Spirit, the spirit of Life, and are moved from the inside toward His teachings: love, help, teaching, guidance, and knowledge of the Gospel. Jesus restores what was lost, and makes all things new. Taste and see for yourself. Learn of Him and be forever changed. I testify that this has happened to me, and that it blew my mind the overwhelming extent of His gift, of the deception I was under, and the Power of His Kingdom. Amazingly astoundingly beyond all comprehension prior to being born again. Unlike anything else I could have ever thought. Best regards, Rick C. Hodgin |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Oct 05 07:23PM +0100 On 05/10/2014 17:14, Rick C. Hodgin wrote: >> arrogant. > I ask you to see for yourself. I testify to what I > have experienced. For each person they too What you have experienced is delusion mate; go see your doctor for some anti-psychotic medication. Evolution = no Abrahamic god (which includes Jesus). /Fibble |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment