Re: [boost] Re: generic uses of optionalT

2003-09-02 Thread Brian McNamara
On Mon, Sep 01, 2003 at 04:05:59PM -0600, Dave Gomboc wrote:
 [Brian McNamara]
 do_something( adapt( 3   ) );
 do_something( adapt( nilableint(3) ) );
 do_something( adapt( foo ) );  // foo has unknown type
 
 But I'd like to write
 do_something(3);
 do_something(foo);  // of type T
 do_something(bar);  // of type nilableT
 
 Can I have my cake and eat it too? ;-)

Yes:

   template class T
   void do_something( T x ) {
  do_something_helper( adapt(x) );
   }
   template class T
   void do_something_helper( nilableT x ) {
  /* actually do it */
   }

(Shameless plus: Note that with FC++, 
   do_something = compose( do_something_helper, adapt );
or
   do_something = do_something_helper ^of^ adapt;
provided that things are defined as functoids.)

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Re: Optional, tie, and iterator_adaptor

2003-09-02 Thread Brian McNamara
On Tue, Sep 02, 2003 at 09:05:59AM +0800, Joel de Guzman wrote:
 My attempt to image optionalT as conceptually a specialized but
 nevertheless, *IS-A* T,  with the added specialization that it can
 be in a dead-uninitialized state. Is a feeble attempt to re-sell the idea
 of the concept that will be immediately obvious to the OO programmer. I
 never really understood why I wasn't able to sell the idea that an
 optionalT is *REALLY REALLY REALLY* nothing else but a 
 union of T and nil.

It's been pointed out before, but to re-emphasize it: from a
type-theoretic standpoint, it is not the case that optionalT-isa-T.
Rather T-isa-optionalT.  (Dog-isa-Animal because Animal has more
possible values.)  I don't mind the suggestive conceptual
analogy/similarity, but when you get down to technicalities, the isa
relationship doesn't hold in the same direction you're saying (in your
first sentence above).


 I agree 200%. I think the *only* meaningful argument against this
 was posed by Brian. That, in C++, you cannot make XT be a
 drop-in replacement of T because implicit conversion will not
 allow code such as:
 
 struct A { void foo(); }
 
 template class T
 void bar(T t) { t.bar(); }
 
 bar(A());
 bar(XA()); // HERE
 
 Unless:
 
 class XT : public T {...};
 
 But then again, that's just a technical impediment.  

As I just mentioned in a previous mail, if bar() has the foresight to
expect this, it can use an adapter in its implementation to smooth out
this issue.  (E.g.
template class T
void bar(T t) { adapt(t).bar(); }
)


As a final aside, I think much of this thread is degenerating into
Parkinson's Bicycle Shed[*], with respect to is it a
pointer/container/X?  At this point, I think we know what set of
methods should be in the interface (indeed, there could be methods both
to return pointers and references; both to throw/fail-undefinedly, etc.)
and the names/documentation issues will fall out with more experience.
Just MO.

[*] See bottom of
   http://www.boost.org/more/discussion_policy.htm

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Re: Re: Re: Optional, tie, and iterator_adaptor

2003-09-02 Thread Brian McNamara
On Mon, Sep 01, 2003 at 09:22:01PM -0600, Dave Gomboc wrote:
 [Fernando Cacciola]
  I'm saying that the choice made by variant in this regards is to the
  code using get as hopeless as undefined behaviour.  I don't think that
  preconditions (and exceptions thereof) should be used to arbitrarily
  make the illusion of giving meaning to an operation that is undefined at
  the conceptual level.
 
 For myself, and I think also for Joel, nil is a fully legitimate value,
 not a hopeless, meaningless, conceptually undefined value.  It's quite
 clear that you don't share this view.  The conceptual divide here is 
 surprisingly large.
 
 I'm surprised to find myself suggesting this, but perhaps instead of
 debating this issue further I and like-interested people should create and
 submit a high-quality implementation of nilable.hpp to Boost.  If
 accepted, people could then choose whichever best meets their
 needs/expectations.

I think this is a good idea too.  Personally, I side with Fernando's
conception of 'optional', but clearly there are two groups which each
want a different (though similar) class.

My contribution with this message is to mention that, rather than
having two completely separate implementations, one could be built atop
the other (or both from a common root).  My hunch is that your nilable
idea could easily be built as a very thin wrapper around optional
(provided optional has a wide enough interface, but I think it does).
Something along the lines of

   template class T
   class nilable {
  optionalT o;
   public:
  T get() {
 if( o ) return *o;
 throw oops;
  }
  // etc.
   };

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Optional, tie, and iterator_adaptor

2003-09-01 Thread Brian McNamara
On Mon, Sep 01, 2003 at 09:03:17AM +0800, Joel de Guzman wrote:
 Do it the ref, tuple and variant way:  get().  But get(), as an
 element-access interface, should return a reference, not a pointer, as
 it does currently. 

Clearly I had not been paying enough attention earlier in the thread; I
was oblivious to the fact that get() was returning a pointer and not a
reference.  I think get() (or operator*(), or however it ends up being 
spelled) should indeed return a reference. 

(Apologies for the confusion.)

As for the use-case with the function returning a pair of iterators
that we'd like to assign to optionals via a tie(), I think there
should also be a different method in the interface which returns the
hole in an empty optional where a new value can be constructed.  See,
e.g., my earlier message which defined an interface with operator+()
and operator~().

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] generic uses of optionalT

2003-09-01 Thread Brian McNamara
On Sun, Aug 31, 2003 at 09:12:59PM -0600, Dave Gomboc wrote:
  The point is that optionalT is not a T, and most notably, a template
  function will never perform the coercion.  Replace the lines like
 B b = get2(args); 
  in your example with real calls to, e.g.
 do_something( get2(args) )
  and do_something() is likely to fail if it's a template function
  (expecting a T and not an optionalT).
 
 Okay, you've demonstrated that it may not be possible to drop-in
 optionalT for T with zero code changes when T is not a scalar type.  
 (Usually, my Ts are! ;-)  Nonetheless, it is at least still possible to
 write generic code that accepts either T or the wrapped T, which is
 definitely an improvement over writing a whack of special-casing code.

Indeed.

[snipped most of code]

 template typename T
 class nilable {
 public:
...
 operator T(void) const {
 if (nil_) throw std::bad_cast();
 return value_;
 };
...

I'd add

  T get() { return T(*this); }   
  // in reality, return T -- using T here just to show the idea

...
 try {
 nilable std::vectorint  nv(v);
 //output(nv);  // true, this fails
 output(std::vectorint(nv));  // but this succeeds!
  
As does

  output( nv.get() );

 nilable std::vectorint  nv2;
 output(std::vectorint(nv2)); // and this throws as expected.

Again I'd prefer

  output( nv2.get() );

I was originally arguing with Joel because I thought he wanted to use
exactly nv and not anything like nv.get().  I think now that we've
cleared up the confusion about get() returning a reference instead of a
pointer, we're all back on the same page.

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: generic uses of optionalT

2003-09-01 Thread Brian McNamara
On Mon, Sep 01, 2003 at 12:13:11AM -0600, Dave Gomboc wrote:
 I've been trying to set things up so that code is written for T that can
 then also use nilableT seamlessly, but doing things the other way around
 might be an improvement.

Agreed.

  [Brian McNamara]
  I was originally arguing with Joel because I thought he wanted to use
  exactly nv and not anything like nv.get().  I think now that we've
  cleared up the confusion about get() returning a reference instead of a
  pointer, we're all back on the same page.
 
 Well, I guess you're still arguing with me ;-) because I _do_ want to use
 exactly nv and not anything like nv.get().  I don't like get() because
 I cannot write x.get() when x is a POD.  This would mean I have to support
 nilableT and T with different code, which is exactly what I'm trying to
 avoid.

This is trivial to fix:

   // Adapters to uniform-ify the interface
   template class T
   nilableT adapt( T x ) { return nilableT(x); }
   
   template class T
   nilableT adapt( nilableT x ) { return x; }

   // generic function
   template class T
   void do_something( nilableT x ) { ... }

   // examples demonstrating how code looks same regardless of type
   do_something( adapt( 3   ) );
   do_something( adapt( nilableint(3) ) );
   do_something( adapt( foo ) );  // foo has unknown type
   
-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


[boost] Reducing template compile-times

2003-09-01 Thread Brian McNamara
Template libraries, especially those employing expression templates,
take a long time to compile.  As an example, one of the example files
for FC++ (parser.cpp) takes about 10 minutes to compile on a blazingly
fast machine with tons of RAM.

I would like to reduce the compile-time.  I solicit any help/advice on
the topic; I am hoping some of the Boost contributors will have run into
this same problem with their own libraries, and have found some ways to
address it.


Here is what I have already figured out.

First off, in FC++, there are a number of templates whose sole purpose
is to provide better compiler diagnostics (along the same general lines
as concept_checks).  I rewrote the library code so that these checks
are only enabled when a certain preprocessor flag is defined.  Turning
off these checks reduced the compile-time of parser.cpp from 10 minutes
to 8 minutes--a significant speedup.

That was the most obvious piece of low-hanging fruit; since the code
to produce the compile-time diagnostics doesn't do anything at run-time,
it was straightforward to just have a switch to turn it on and off.

I imagine there are other things I can do to rewrite some of the
library templates that are doing real work so that they compile
faster.  Specifically, I imagine that some templates can be rewritten so
that they cause fewer auxiliary templates to be instantiated each time
the main template gets instantiated.

However there are two issues that make this hard to do:

  (1) Knowing which templates to focus on.  That is, which templates
  are effectively the inner loops in the compilation process, and
  thus deserve the most attention when it comes to optimizing
  them?

  (2) Knowing how to rewrite templates to make them faster.  I imagine
  that fewer templates instantiated will mean faster compile
  times, but I don't actually know this for sure.  I have no
  window into what the compiler is actually doing, to know what
  takes so long.  Maybe it's the template instantiation process;
  maybe it's all the inlining; maybe it's the code generation for
  lots of tiny functions.  I don't know.

I have made some headway with (1): the unix utility nm lists all the
symbols compiled into an executable program, and by parsing the output,
I am able to determine which templates have been instantiated with the
most number of different types.  My little script yields output like
...
313  boost::fcpp::lambda_impl::exp::Value
314  boost::fcpp::lambda_impl::BracketCallable
606  boost::fcpp::lambda_impl::exp::CONS
609  boost::fcpp::full1
610  boost::intrusive_ptr
670  boost::fcpp::lambda_impl::exp::Call
which tells me that the Call template class has been instantiated 670
different ways in parser.cpp.  This at least gives me some idea of
which classes to focus my optimizing attention on.  However a drawback
of using the nm approach is that it only shows templates with
run-time storage.  There are tons of template classes which contain
nothing but typedefs, and I imagine they're being instantiated lots of
ways too, and I don't know if this slows stuff down significantly too.

As to (2), I know nothing, other than the speculation that fewer
instantiations is better.

So, that's where I am.  Help!  :)

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Optional, tie, and iterator_adaptor

2003-08-31 Thread Brian McNamara
So I completely disagree that optionals should mix the interfaces of
optional and the wrapped object into one.  I think there should be an
explicit unwrapping operation.  But this is just my opinion, based on no
practical evidence/experience, and I'm sure there are trade-offs either
way.  I'll explain the crux of my own reasoning below.

On Sun, Aug 31, 2003 at 11:59:42PM +0800, Joel de Guzman wrote:
 It's really strange (and hard to explain) that you have to dereference
 optionalB. Example:
 
 F(tupleA, optionalB, C args)
 {
 A a = get1(args);
 B b = *get2(args); // strange!
 C c = get3(args);
 }

I don't think it's strange at all; an optionalB is not a B!

 Not only is it strange, it complexifies the code a lot when the code is
 automatically generated by some meta-program. Example:
 
 template class A, class B, class C
 F(tupleA, B, C args)
 {
 A a = get1(args);
 B b = get2(args); 
 C c = get3(args);
 }
 
 Whoops, have to do a special case IFF B is an optional!

Well, no.  B==optionalBprime via template unification, right?
If you want to do something with a Bprime, then yes, you have to
special-case it, as you should.


Here's a (contrived) example of how the implicit conversion breaks 
generic code:

   template class Container
   void contrived( Container c ) {
  c.begin();
   }
   ...
   vectorint v;
   contrived(v);   // fine
   optionalvectorint  ov( v );
   contrived(ov);  // fails

The point is that optionalT is not a T, and most notably, a template
function will never perform the coercion.  Replace the lines like
   B b = get2(args); 
in your example with real calls to, e.g.
   do_something( get2(args) )
and do_something() is likely to fail if it's a template function
(expecting a T and not an optionalT).


As another example, FC++ lists support conversion-to-bool as a test for
NIL:
   fcpp::listint l = NIL;
   if( l )  // if l not empty
  cout  head(l);  // print first element
Clearly if 'l' were an optional, the if test would have a different
meaning.  I know you've been supporting a separate way to do the test
(with ==none), but I think that's completely arbitrary.  The two
issues are both really the same issue, in my mind.  
   

 Of all the types involved in the passing of arguments to the semantic
 actions, the optional doesn't fit nicely because it is the only one
 that has mixed value/pointer semantics. I am tempted to not use
 optionalT because of this and instead use variantT, none,
 but I hate to miss the performance advantage of optional vs.
 variantT, none. 

I have not used variant and know little about it, but I imagine you have
to explicitly tell a variant which type you expect to get out of it.
I think the same is true of optional; the call to operator*() (or
whatever) says I want the T type (rather than the 'none').

My two cents.  Again let me stress I'm arguing based on no practical
experience working with any of these datatypes.

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Optional, tie, and iterator_adaptor

2003-08-31 Thread Brian McNamara
On Sun, Aug 31, 2003 at 10:41:15AM -0700, Mat Marcus wrote:
 --On Sunday, August 31, 2003 10:29 AM -0400 Brian McNamara 
 First off, let me say I do think this is a compelling use-case.
...
 I missed the beginning of this thread, but I imagine the motivation
 is to avoid having to say
std::pairIter,Iter p = out_edges(v,g);
Iter begin = p.first;
Iter end   = p.second;
 each and every single time you call out_edges().
 
 IIUC, you are saying that you don't find the use of tie with pairs
 very compelling. Fair enough. Of course tie is more generically useful
 with arbitrary tuples and multi-value returns. I was just trying to
 present a small familiar example of such usage.

Apologies if I was unclear; I _do_ think it's compelling.  The syntactic
convenience of being able to bind multiple names in one expression is
very nice.  (Additionally, if you're doing lots of FP stuff (like me),
it's a real pain when you have to introduce those nasty _statements_
into your code, when you'd really like to do things all in one big
_expression_.  :)  )


 In general I'm not a fan of implicit conversions or constructors.
 However one of my goals is to be able to easily/readably move code
 from using raw variables to use PossiblyUnitinitializedVariables
 instead. So..

I agree that it would be nice for PossiblyUnitinitializedVariables to be
able to be included in existing code with a minimum of fuss.  I think,
perhaps, that that goal is incompatible with avoiding implicit
conversions, though.

 ... here I like the + or something like it
 begin.reference_to_uninitialized(). That is I don't mind when users
 have to be a little more explicit in the dangerous/uncommon case. ~ is

Indeed (make the easy/common things easy, and make the hard/uncommon 
things possible).

 also interesting, although I think that readability suffers. I'd give
 up bool conversion and operator! to avoid the need for ~ if that would
 reasonably solve the muddling issues. But perhaps there would be too
 many other problems -- I haven't explored this deeply yet.

Right; to clarify, I don't think the boolean conversion operator is
interfering with the implicit conversion to T.  Rather I think each is
an instance of implicit conversion, and implicit conversions just
don't work well with templates in general, in my experience.  

I chose '+' and '~' simply because they were the two unary operators
that sprang to mind (that aren't named '*').  Personally I have no
problem with '*'; C++ has a small finite set of operators, and so you
are bound to have to overload the conceptual meanings of some operators
if you want to use them for useful syntax sugar.  The way I see it, the
optional interface using '*' is fine, and I think perhaps what people
object to is the conceptual notion of optional being 'pointer-like'.
The way I choose to see it, optional is just a special kind of
container, which happens to use '*' to get at the value in the
container, and the fact that '*' is also used to dereference pointers
is a mere coincidence of names.

But perhaps other operators (like '+' and '~') or named operations
would be more generally acceptable.  That's fine.  My main point in
joining this discussion was to emphasize that I think there ought to be
an explicit operation to 'get' the value of an optional (as well as to
get the location of raw storage to construct a new value).  What those
operations are named matters much less than simply their existence.

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Optional, tie, and iterator_adaptor

2003-08-31 Thread Brian McNamara
On Sun, Aug 31, 2003 at 11:11:10AM -0700, Mat Marcus wrote:
 --On Sunday, August 31, 2003 1:35 PM -0400 Brian McNamara 
 On Sun, Aug 31, 2003 at 11:59:42PM +0800, Joel de Guzman wrote:
 It's really strange (and hard to explain) that you have to
 dereference optionalB. Example:
 
 F(tupleA, optionalB, C args)
 {
 A a = get1(args);
 B b = *get2(args); // strange!
 C c = get3(args);
 }
 
 I don't think it's strange at all; an optionalB is not a B!
 
 That doesn't make it a pointer to B!

True.  See my message of a moment ago, where I adopt the notion that
'*' is just an unfortunate coincidence of names, and that any
relationship between optional and pointers is mere happenstance.  (This
all despite the documentation on optional which explicitly describes
the relationship; I am merely trying to present another way of looking
at it which may be useful.)

 As another example, FC++ lists support conversion-to-bool
 
 There's conversion-to-bool again. I still wonder whether dispensing 
 with this would open the door to implicit conversions.

I think no.

I should mention in passing that, while in general I think implicit
conversions are bad news and should be avoided whenever reasonable, I
do think the conversion to bool is an exceptional case, simply because
it is already so deeply ingrained in C++ (and C) language/culture.

(Fortunately bool has a very narrow interface, so it doesn't get us into
too much trouble.  Implicit conversions to user-defined types may create
arbitrary interface conflicts/conceptual ambiguities, and this is where
the real trouble begins.)

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: lexicographic: review request?

2003-08-30 Thread Brian McNamara
 The point is, that Jan proposed to add something which has a hidden 
 overhead and I'm not sure it's a good idea. Instead of nested 
 if-else-cascades, the user could also write:
 
 bool operator( const person lhs, const person rhs )
 {
return
   lhs.lastname != rhs.lastname ? lhs.lastname  rhs.lastname :
   lhs.firstname != rhs.firstname ? lhs.firstname  rhs.firstname :
   lhs.age  rhs.age;
 }

I am (re)appearing mid-thread, so I may have missed something along the
way, but...

What's with !=?  I think lexicographical orderings are built only on
the assumptions of operator, yes?  For two objects x and y, if neither
   x  y
nor
   y  x
is true, then they are in the same equivalence class, but this is not
the same thing as equality or inequality.

I just want to make sure the template parameter constraints (or macro
parameter constraints, as the case may be) are the right ones.

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: boost/detail/iterator.hpp update

2003-08-30 Thread Brian McNamara
On Thu, Aug 28, 2003 at 03:05:19PM -0400, David Abrahams wrote:
 Douglas Gregor [EMAIL PROTECTED] writes:
  On Thursday 28 August 2003 01:23 pm, David Abrahams wrote:
  The other possible option would have been to simply not give the user
  a readable error message.  I'm open to opinions that I chose the
  wrong balance.
 
  So we're breaking code in order to produce a better error message? This seems 
  like the wrong trade-off to make, especially because it means it breaks code 
  when users upgrade from VC6 to VC7; but we want them to upgrade! 
 
 Anyone got a brilliant way to cause vc7 to print the error message?

More generally, is there a generally accepted strategy for Boost
libraries to attempt to force compilers to emit useful diagnostics?

I can imagine there are a number of places where this goes on, and so if
anyone has good domain knowledge about coercing compiliers into emitting
useful diagnotics, it'd be great to have that written down somewhere (or
maybe even turned into some macros possibly).

(Kinda a vague idea-specification, I know.)

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Do-nothing binary function

2003-08-30 Thread Brian McNamara
On Thu, Aug 28, 2003 at 03:59:19PM +0400, Vladimir Prus wrote:
 Would it be desirabe to have such class? I'm thinking about 
 
 struct do_nothing {
   templateclass T
   void operator()(const T) const {}
 
 templateclass T1, class T2
void operator()(const T1 t1, const T2 t2) const {}
 
//
 }

Someone has already commented WRT bind/lambda.  Just FYI (as more
support that, yes, it can be generally useful), in FC++

   no_op

is the (nullary) do-nothing function object, and thus

   ignore(ignore(no_op))

is the function you've written above.  (ignore() is a combinator which
takes a function and returns a new function which takes an extra first
argument and ignores it.)

 And another question. Do we have a functional object which always returns 
 true, and can be called with two arguments of any types? Again, some BGL 
 header has such a class in detail namespace.

Again, I imagine you do something similar with bind/lambda; in FC++:

   ignore(ignore(const_(true)))
or
   lambda(X,Y)[ true ]

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: lexicographic: review request?

2003-08-23 Thread Brian McNamara
On Sat, Aug 23, 2003 at 11:21:03AM +0200, Daniel Frey wrote:
 a) Short-circuiting
 b) Unnamed functions
 
 Jan Langer wrote:
 bool operator  (person const p1, person const p2)
 {
 return boost::lexicographic
 (p1.lastname, p2.lastname, cmp_lower)
 (p1.firstname, p2.firstname, cmp_lower)
 (p2.age, p1.age);
 }
 
 The two points listed above are both visible here: Even if there are no 
 persons with the same name, age is accessed. Even worse, it may be a 
 costly method age() and the unaware user creates much worse code than 
 using nested if-else-structures.
 
 Also, you might not want to define operator. Sometimes, you just need 
 it in one place, e.g. std::sort( v.begin(), v.end(), /*HERE*/ );

I have imagined another syntax which addresses the issues somewhat:

   // use boost::lamdba
   boost::lexicographicperson
 ( _1.first,cmp_lower )/* see below */
 ( _1.last, cmp_lower )
 ( bind(T::age,_1) /* use default cmp */ )
 ( p1, p2 )

The basic idea is you say lexicographicT to start creating a
comparator for T objects, and then use continual argument lists (as in
the original example), but where each argument list is either
( lambda(T){ return T.component }, component_comparator )
or
( lambda(T){ return T.component } )  // uses default comparator
Finally, when you see an argument list with arguments of type
( T, T )
you know you are done and it is time to compare now.  Of course, if you
leave off this final argument list, then you get back a function object
which can be passed, e.g., to std::sort() as in the example above.

The problem (cited see below) is that since operator . isn't
overloadable, the boost::lambda expressions like _1.first don't
actually exist.  Offhand I dunno if C++ in general or Boost in
particular offers a nice way to lambda-ify such a member-variable
expression.

Anyway, just wanted to share some ideas which I think may be a good
direction to go to address the issues Daniel raised. 

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: lexicographic: review request?

2003-08-23 Thread Brian McNamara
On Sat, Aug 23, 2003 at 09:45:42AM -0400, Brian McNamara wrote:
// use boost::lamdba
boost::lexicographicperson
  ( _1.first,cmp_lower )/* see below */
  ( _1.last, cmp_lower )
  ( bind(T::age,_1) /* use default cmp */ )
  ( p1, p2 )
...
 The problem (cited see below) is that since operator . isn't
 overloadable, the boost::lambda expressions like _1.first don't
 actually exist.  Offhand I dunno if C++ in general or Boost in
 particular offers a nice way to lambda-ify such a member-variable
 expression.

I just looked at the boost::lambda documentation and see that they were
clever enough to make bind() work on member variables as well as member
functions.  So the actual syntax would be

   // Assume p1.first, p1.last, and p1.age() are all legal
   boost::lexicographicperson
 ( bind(T::first,_1),  cmp_lower )  
 ( bind(T::last,_1),   cmp_lower )
 ( bind(T::age,_1) /* use default cmp */ )
 // above returns a comparator object; can add
 ( p1, p2 )
 // to call it if desired

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] FC++ integration/future issues (was Some FC++ comments)

2003-08-17 Thread Brian McNamara
On Fri, Aug 15, 2003 at 02:44:20PM -0400, Joel Young wrote:
 I tried using FC++ a while ago for flexibly expressing and passing
 around linear algebra pipelines and I found this lack of mutable
 reference parameters to be highly constraining and insanely frustrating.
 I wanted to be able to take a reference to a vector as a parameter and
 return that same vector, mutated, as a return value.  I started to hack
 FC++ to remove the const on the references but after a bit gave up.

I should have mentioned as an aside what I did in FC++ for input/output;
I made functoids in_stream and out_stream which take pointers to streams
as the lhs:

   cout ^out_stream^ x ^out_stream^ y ^out_stream^ z;
   // cout  x  y  z;

This is one way to functoidize such operations.  It's unclear to me
if/how useful this is.


A question I should I asked before: why were you using FC++ in the
first place?  (That sounds too accusatory. :) )  What feature(s)
motivated its use?  Can you give an example of a linear algebra
pipeline that you might want to express as a functoid (or something)?
I'm afraid I don't have a good enough sense of the domain and what FC++
features you wanted; there may be some useful solution along a
completely different path...

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


[boost] FC++ integration/future issues (was Some FC++ comments)

2003-08-15 Thread Brian McNamara
On Fri, Aug 15, 2003 at 11:29:49AM +0200, Hartmut Kaiser wrote:
 You've done a great piece of code! I've tried to understand your
 articles about the differences between fcpp and boost::lambda/bind/etc.
 and these (the differences) are now clear to me (to some degree :-).
 
 OTOH I know, that there is going on serious work to merge boost::lambda
 with Phoenix to overcome some well known limitations of both and to
 avoid having two similar libraries in boost. Wouldn't it be nice, if
 after this merger we'd get _one_ library lambda + phoenix + fcpp? Or
 isn't this possible at all?

It may well be possible.  I have had a little bit of discussions with
Jaakko and Joel (off-list) about this.  I have not had the opportunity
to think deeply about it though; it is unclear to me if the FC++
implicit assumption of 'value semantics' (FC++ doesn't allow (mutable)
reference parameters) will throw a wrench in the works.  It is also
unclear to me how much rework such an integration might necessitate.
(I am very pleased to say that integrating/reusing other (small)
portions of boost in FC++'s implementation went very smoothly.)


This begs another important (at least to me :) ) question about FC++ and
Boost.  Can FC++ be accepted into Boost prior to any integration with
lambda/phoenix/bind?  I hope that the answer is yes, for a few reasons:
 - It will give the boost user/developer community the opportunity to
   gain some experience with FC++, to see better what its merits and 
   demerits are.
 - It will provide an opportunity to see how well/badly the various 
   libraries interoperate now (as separate libraries), which may expose
   more of the important integration issues.
 - It means less time for FC++ to languish in the current state it's in,
   where I'm doing work to `boostify' and improve it, but no one is
   using it.
I'm still a newbie to this community, so I have no idea what the opinion
of the `ruling committee' is (or will be) on these issues.  But it would
be helpful to me to know (at least to have a better idea where my
immediate future lies).

So if anyone has opinions or constructive thoughts on this issue, I'd
like to hear them.

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] FC++ integration/future issues (was Some FC++ comments)

2003-08-15 Thread Brian McNamara
On Fri, Aug 15, 2003 at 02:44:20PM -0400, Joel Young wrote:
 From: Brian McNamara [EMAIL PROTECTED]
  to think deeply about it though; it is unclear to me if the FC++
  implicit assumption of 'value semantics' (FC++ doesn't allow (mutable)
  reference parameters) will throw a wrench in the works.  It is also
 
 I tried using FC++ a while ago for flexibly expressing and passing
 around linear algebra pipelines and I found this lack of mutable
 reference parameters to be highly constraining and insanely frustrating.
 I wanted to be able to take a reference to a vector as a parameter and
 return that same vector, mutated, as a return value.  I started to hack
 FC++ to remove the const on the references but after a bit gave up.

Yes... square peg, round hole.  (You can use pointers, but this
sometimes turns existing code into mess of s, *s, and
compose(dereference)s.)

An open question (which someone on the list suggested) is whether
monads will provide a convenient interface to bring mutation cleanly
back into the mix.  That's what happens, e.g., in Haskell.  But the
monad stuff in FC++ is really new (and monads are still pretty new to
me), so it isn't yet clear if/how this may address the issue.

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Some FC++ comments

2003-08-14 Thread Brian McNamara
On Wed, Aug 13, 2003 at 11:27:08PM -0400, Brian McNamara wrote:
 I've been working on a draft of the documentation for the boostified
 version of FC++, and it's finally reached a good enough state to be
 potentially useful to you-all.  Check out
 
http://www.cc.gatech.edu/~yannis/fc++/boostpaper.pdf
 
 (I'll make it available in a more convenient format when I figure out
 how to work latex2html.)  

Got it working:
   http://www.cc.gatech.edu/~yannis/fc++/boostpaper/
is the HTML version.

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Some FC++ comments

2003-08-14 Thread Brian McNamara
On Mon, Jul 28, 2003 at 03:16:52PM -0400, Brian McNamara wrote:
 functional programming.  Over the next couple of weeks I will make 
 documentation of the boostified version of FC++ that's aimed at a C++ 
 audience.  Hopefully that will help.

I've been working on a draft of the documentation for the boostified
version of FC++, and it's finally reached a good enough state to be
potentially useful to you-all.  Check out

   http://www.cc.gatech.edu/~yannis/fc++/boostpaper.pdf

(I'll make it available in a more convenient format when I figure out
how to work latex2html.)  

I'm also working on improving the example files, and using some of the
other constructive comments I've received.  Any and all feedback is
appreciated.

As a reminder, here is where to find the 'boost' version of the library:
 I have posted the first boostified version of FC++ to the YahooGroups
 files section; it is called fcpp.
http://groups.yahoo.com/group/boost/files/

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] bind/lambda - unsupported use case?

2003-08-14 Thread Brian McNamara
On Mon, Aug 11, 2003 at 10:54:40PM -0500, Aleksey Gurtovoy wrote:
 Gary Powell wrote:
  Consider the following snippet:
  
  void show_warning( message_dialog const, user_message );
  void post_command( boost::functionvoid() );
  
  int main()
  {
  boost::functionvoid( user_message ) f( 
bind( post_command
  , ( bind( show_warning, message_dialog(), _1 ) )
  // what goes here?
  )
  );
  }
  
  Could we make it work, somehow? Offers of a hand-written function 
  performing the composition are not accepted :)
  
  
  I'm a bit confused by your request,
   Do you want both fns to be called? 
 
 Nope. Please see http://article.gmane.org/gmane.comp.lib.boost.devel/23466
 for the semantics clarification. Basically, I want the whole bind 
 expression to return an unary function object which, when invoked, will
 use the argument to construct a nested nullary function object:
 
 bind( show_warning, message_dialog(), arg )
 
 and pass it as an argument to 'post_command'.
 
 Does it make more sense now?

I can't speak for bind/lambda, although I imagine there must be a way,
probably involving delaying the evaluation of _1 for one step.

Using FC++, it would be

   using fcpp::fun1;
   using fcpp::lambda;
   using fcpp::ptr_to_fun;
   fun1user_message,void f =
  lambda(X)[ ptr_to_fun(post_command)[
 lambda()[ ptr_to_fun(show_warning)[ message_dialog(), X ]
] ] ];

The explicit lambda notation makes it easier to (mentally and
syntactically) sort out functions like these where the placeholder
variables are bound by a lambda (bind expression) other than the
innermost one.

(The calls to to ptr_to_fun above are necessary only to promote the
function pointers into FC++ functoids.)

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Some FC++ comments

2003-07-28 Thread Brian McNamara
On Mon, Jul 28, 2003 at 05:38:01PM +0200, Miroslav Silovic wrote:
 Well, nobody posted anything definite on FC++, which is a pity, since I 
 find this library potentially very useful. Here are some comments. 
 Caveat: I haven't extensively used the library, but I have quite a bit 
 of experience with functional programming. I won't comment on the naming 
 scheme or the docs - that was covered in the original post.

I expect the docs are a big issue (as David Abrahams commented); most of 
the docs on the web site are aimed at an audience of researchers in 
functional programming.  Over the next couple of weeks I will make 
documentation of the boostified version of FC++ that's aimed at a C++ 
audience.  Hopefully that will help.

 First, FC++ duplicates Boost::bind with its currying. Are there any
 plans to reuse the Boost code for this? Boost::bind seems more powerful
 and general, in that it can take functions with any arity and bind any
 argument(s).

(Perhaps again this is the fault of the documentation being poor.)  FC++ 
full functoids are fully curryable by default.  The prefix and 
underscore styles of currying are the preferred ways to do things.
See   http://www.cc.gatech.edu/~yannis/fc++/currying.html
for some examples.  You can do the same things with boost::bind (or 
boost::lambda, or fcpp::lambda) too.  I am talking to Jaakko and Joel 
(off-list) about the boost infrastructure there to ensure that, at the 
least, FC++ interoperates with the boost stuff, and at best, that much 
of the infrastructure can be reused.

 I think FC++ could profit from pluggable memory management, perhaps as a 
 policy parameter. In particular, zonal allocation could allow one to do 
 away with refcounting for calculate-and-exit trips into FC++ code (where 
 you just carve small chunks from a list of memory pages, then nuke the 
 entire block once you're done with the calculation).

This sounds like an interesting extension, though I don't know that I
would be the right person to implement it.  :)

 One interesting Haskell feature that FC++ doesn't have are monadic 
 arrays. Are there any plans to communicate with writable STL containers 
 using monads?

The monad stuff is very new; this sound like a terrific idea.  I'll put it
on my to-do list.

 I also couldn't find any reference to tuples in the docs. Is there any 
 support for them? (This could be a low-hanging fruit, since Boost 
 already has tuples).

There is nothing (other than std::pair and fcpp::mk_pair).  I don't see
any reason boost tuples couldn't be used in fc++ code, though.

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Preliminary submission: FC++

2003-07-28 Thread Brian McNamara
Based on David's suggestion, I'll try to briefly define all the terms
I've used in my earlier post.

 Brian McNamara [EMAIL PROTECTED] writes:
  I have posted the first boostified version of FC++ to the YahooGroups
  files section; it is called fcpp.
 http://groups.yahoo.com/group/boost/files/
 
  --
  Background
  --
  FC++ is a library for functional programming.  In FC++ we program with
  functoids (classes which define operator() and obey certain other
  conventions).  The library features include:

In the latest version of the library, we discriminate among a few kinds
of functoids:
 - A basic functoid is a class which defines a (possibly templated) 
   operator() function, as well as a templated sig member structure.
   (The sig in FC++ is analogous to the result structure for
   the proposed result_of construct for computing result types.)
 - Most functoids are direct functoids, as they call their
   implementation function directly.  In contrast, indirect functoids
   use dynamic dispatch (virtual function call), in order to create
   function variables.  FC++ indirect functoids are almost completely
   analogous to boost::function objects:
  fcpp::fun2int,int,int f = fcpp::plus;  // select (int,int)-int
  f(3,2);   // yields 5
  f = fcpp::minus;
  f(3,2);   // yields 1
 - Indirect functoids must always be monomorphic (non-templated).
   That is, given an indirect functoid (like f above), it expects a
   fixed set of arguments types (e.g. ints).
 - Direct functoids can be polymorphic (templated).  For example, 
   fcpp::plus is polymorphic:
  plus(3,3);// yields int 6
  plus(2.2,2.2);// yields double 4.4
  plus(s,s);// if s is std::string(foo), yields foofoo
   Unlike indirect functoids, you can't create variable direct
   functoids.  The type of the object fcpp::plus is fcpp::plus_type.
 - Full functoids are basic functoids which have been wrapped by the
   fullN wrapper class.  Full functoids add extra FC++ functionality,
   like currying, lambda awareness, and infix syntax (see below).

(Note that the FP community uses polymorphism to mean templates,
whereas the OO community uses the term to mean dynamic dispatch.  
An unfortunate overloading of terms.  As you can see, we use the FP
definition throughout the FC++ documentation.)
  
   - higher order, polymorphic (template) functions (direct functoids)

Higher order functions are functions which take other functions as
arguments or return functions as results.  In FC++, since we represent
polymorphic (template) functions as direct functoids (which, unlike C++
function templates, are C++ objects which can be passed around as
parameters), we can implement functions which are simultaneously
higher-order and polymorphic.  An example is compose:
   // compose(f,g)(args) = f( g(args) )
If add_self is this polymorphic function:
   // add_self(x) = x + x
Then we can write
   compose( add_self, add_self )( 3 );   // yields 12
   compose( add_self, add_self )( s );   // yields foofoofoofoo (s as above)
(This feat was a novelty when FC++ was new, but is becoming more
mainstream in C++ now, owing to the more general knowledge of
techniques along the lines of result_of, which enables the result 
type of template functions to be named.)

   - lazy lists

More generally, a number of data structures and functions which employ
lazy evaluation.  As an example,
   fcpp::listint l = enum_from(1);
results in l being the infinite list of integers [1,2,3...].  The
elements in the list are not computed until they are demanded (lazy
evaluation).  

   - library of useful functions, combinators, and monads (mostly
 mimicking the Standard Library of the language Haskell)

Combinators are higher-order functions.  (Definitions of the term
combinator seem to vary from community to community.)  Monads cannot
be defined in a sentence or two, so I won't try.

(Much of FC++ was designed to imitate Haskell, which is kinda the
cutting edge, mainstream pure functional language.)  

   - currying

Given some 3-argument function f:
   f(x,y,z)  // normal call
   f(x,y)// new function g, where g(z)=f(x,y,z)
   f(x)  // new function g, where g(y,z)=f(x,y,z)
   f(x,_,z)  // new function g, where g(y)=f(x,y,z)
   etc.
FC++ full functoids exhibit built-in currying.  This is basically a
terser syntax for what boost::bind does.

   - infix function syntax

Given a two-argument function f:
   x ^f^ y  // same as f(x,y)
This is syntax sugar.  Often things like
   x ^plus^ 3
are easier to read than
   plus(3,x)
because it seems more natural.  (Haskell uses ` instead of ^)

Of course, if f is a 3-arg full functoid, then
   x ^f^ y// new function g, where g(z)=f(x,y,z)

   - dynamically bound functions (indirect functoids)

Described above.

   - effect combinators

Suppose write_log is a function which takes a string and writes it to a
log file, and do_foo is a function that does something

[boost] Preliminary submission: FC++

2003-07-15 Thread Brian McNamara
I have posted the first boostified version of FC++ to the YahooGroups
files section; it is called fcpp.
   http://groups.yahoo.com/group/boost/files/

--
Background
--
FC++ is a library for functional programming.  In FC++ we program with
functoids (classes which define operator() and obey certain other
conventions).  The library features include:
 - higher order, polymorphic (template) functions (direct functoids)
 - lazy lists
 - library of useful functions, combinators, and monads (mostly
   mimicking the Standard Library of the language Haskell)
 - currying
 - infix function syntax
 - dynamically bound functions (indirect functoids)
 - effect combinators
 - interfaces to STL via iterators
 - ways to transform normal C++ functions/methods into functoids
 - a lambda sublanguage, with syntax for lambda, let, letrec,
   do-notation, and monad comprehensions

Much of the documentation for FC++ can be found at
   http://www.cc.gatech.edu/~yannis/fc++/
and the rest appears linked from
   http://www.cc.gatech.edu/~yannis/fc++/New1.5/
(which has a pre-release of the upcoming version (v1.5), currently out
for beta-testing).  The upcoming release comprises about 9000 lines of
code and compiles on a number of different compilers (g++, Comeau,
Intel, MSVC++).

Note that all the documentation on our web site uses FC++ identifiers 
rather than Boost FC++ identifiers.  (See below.)

---
Boostifying
---
I have asked a few questions on the boost mailing list about what would
need to be done to FC++ to boostify it.  I received a number of useful
comments.  Here are the things that have changed from FC++ to the
submission I just posted to the YahooGroups page (I shall henceforth 
refer to that submission as Boost FC++):

 - Changed naming convention of all types/objects/functions in the 
   public interface to conform with Boost naming conventions.  
   (e.g. enumFrom is now enum_from; EnumFrom is enum_from_type.)

 - Reused boost libraries as appropriate.  Specifically, I have reused
   these items from boost:
- shared_ptr   - addressof
- intrusive_ptr- noncopyable
- is_base_and_derived  - type_with_alignment
- is_convertible   - alignment_of
   (I compiled against boost_1_30_0.) I should probably also reuse some
   of mpl, but I have not yet studied that library enough to use it.

 - Changed file names so that headers have .hpp file extensions, and
   clients have .cpp extensions.

 - Moved library into namespace boost (::boost::fcpp).

 - Boost FC++ full functoids meet the demands of the proposed 
   result_of template, for forward compatibility with boost/std 
   library template adaptables.

 - The code posted to YahooGroups has been tested on g++-3.1.1 for Solaris 
   and on icc7 for linux.  Prior versions of FC++ have also been tested
   on Comeau and VC++7.1.  I expect that this code should be reasonably
   portable.

-
Known future work
-
There are still a few issues which need tending to which I am aware of.
They are:

 - Documentation.  There are a number of research papers and tutorials
   about FC++ on our web site (mentioned in the Background section,
   above).  However there is not yet good documentation for Boost
   FC++.  I need to create a document which (1) describes everything in
   one place, (2) is aimed at a C++ audience, and (3) uses the new
   Boost FC++ identifiers.  Additionally there will need to be a bit of
   documentation describing how Boost FC++ relates to the rest of Boost
   (especially lambda, bind, and function).

 - The header files define objects (in an unnamed namespace) by default.  
   (Read about FCPP_DEFER_DEFINITIONS at
  http://www.cc.gatech.edu/~yannis/fc++/FC++.1.4/changes.html
   for a short description.)  I am not sure if this behavior is
   objectionable or not.  Ask me more if you're confused.

 - There is probably a way to adapt some functoids which work on 
   boost::fcpp::list objects so that they can read arbitrary containers
   (really, iterator ranges).  I should add a little more support for
   using Boost FC++ functoids on std:: data structures.

 - Copyright notices.  The header files contain the FC++ copyright
   notice; the clients (.cpp) contain none.  I've heard a bit about a
   standard Boost license being developed; perhaps by the time (if/when) 
   FC++ gets added, that will be complete.  In any case, the boost
   copyright/licensing issues as I understand them are all acceptable to
   Yannis and me (the FC++ authors).

--
Refinement
--
FC++ is a big library and I expect there will be a number of things
needing refinement to make FC++ acceptable to Boost.  I hope this
message will start that discussion.

Thanks,
  Brian

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: functors for taking apart std::pair?

2003-07-12 Thread Brian McNamara
On Sat, Jul 12, 2003 at 01:21:49PM +0100, Andy Sawyer wrote:
 There's a third form I've also found useful on occasion:
 
 struct selector1st
 {
   templatetypename Pair
   const typename Pair::first_type operator()( const Pair a ) const
   {
 return a.first;
   }
 };
 
 Which has the advantage of not needing to specify _any_ type at the call
 site:
 
 for_each( map.begin(), map.end(), selector1st() );
 
 And again, is not limited to use with std::pair. However, it's utility
 is limited by not inheriting from std::unary_function. 

If and when I get FC++ ( http://www.cc.gatech.edu/~yannis/fc++/ ) into
Boost, FC++ has the same kind of selectors you've shown above (named
fst and snd, as in Haskell).  Whereas these function objects also
cannot be used with STL algorithms requiring adaptables (for the reason
you mention above), it can be used with the analogous algorithms in
FC++, since the FC++ infrastructure enables return-type-deduction for
template function objects.

I've been working on boostifying FC++ this past week (adopting naming
conventions, reusing Boost code, etc.) and will hopefully get a
Boost-ful FC++ version up for review in the next two weeks or so.

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Interest in FC++?

2003-06-26 Thread Brian McNamara
On Thu, Jun 26, 2003 at 01:36:58PM +0200, Dirk Gerrits wrote:
 Brian McNamara wrote:
  - Reuse: FC++ reinvents a number of Boost's libraries in its
   implementation, such as smart pointers and metaprogramming
   tricks.  A Boost version of FC++ should reuse Boost libraries for
   this.
 
 I agree. While FC++ probably would bring in a lot of new stuff, there is 
 *considerable* overlap with Boost's current libraries.
 On the function side there's: bind, mem_fn, compose, function, 
 functional, and of course lambda. And then there are smart_ptr, mpl, and 
 preprocessor.
 
 Reusing will probably make the implementation a lot cleaner, potentially 
 more robust, and ...

I have taken a closer look at what is and is not reusable.  Here's what
I've come up with:

Reusable: 
   smart_ptr: boost::shared_ptr and boost::intrusive_ptr seem to do
  exactly the same thing as fcpp::Ref and fcpp::IRef

   mpl: it looks like some things here, like if_ and find can be reused.
There may be more, too.

   type_traits: boost::is_base_and_derived replaces fcpp::Inherits

   concept_check: it may be possible to re-use some of the machinery
  here for reporting custom error messages.

Non-reusable:
   bind, mem_fn, compose, function, functional, lambda:
  (It looks like much of compose and functional is subsumed by
  bind/lambda anyway.)  FC++ indirect functoids are similar to
  boost::function objects.  fcpp::ptr_to_fun is similar to bind 
  and mem_fn.  fcpp::lambda is somewhat similar to boost::lambda.
  In each of these cases, however, none of the boost stuff can be
  reused in FC++, as FC++ uses/requires so-called full functoids
  to work.  FC++ must necessarily duplicate these, owing to the
  fundamental differences in the library architecture.

  - Naming conventions: FC++ uses a naming convention other than Boost's
   (including systematically using capital letters in identifiers).
 
 From what I have been able to tell in such a short time, the 'camel 
 hump notation' is mostly used in the implementation and only slightely 
 so in the interface. For example, things like Fun0, Fun0Impl, ... are no 
 problem because you want to reuse Boost's facilities for these anyway. 
 And the functiods are already 'properly' named in lowercase. Of course, 
 there is some work to be done here, but I don't think it would be a big 
 problem, do you?

It's much more insidious than this.  There are a number of types of
names which use captial letters visible in the client interface to the
FC++ library.  Here are the major categories of examples that spring to
mind:

   Functoids.  Every functoid (like id, map, enumFrom, compose) is an
   instance of a corresponding data type which begins with a capital
   letter (Id, Map, EnumFrom, Compose).  Being able to name the type of
   any functoid is important.

   Data types.  Classes like List and Maybe have names starting with
   capital letters.

   Signature information.  We use names like Arg1Type, Arg2Type,
   and ResultType as typedefs for functoid signatures.

   LEType computer.  Lambda expressions' types are named by the LEType
   computer, which uses some all-caps names like LAM, LV, CALL, etc.

While some of these names are ones that I have made up, and thus can be
changed on a whim to lowercase versions, there are still two classes
of naming issues which I hesitate to change:

   Haskell names.  Many functoids (like enumFromTo, takeWhile, zipWith,
   etc.) and datatypes (like Maybe) have the exact same names and 
   behavior as their counterparts in the Haskell programming language.  
   I've named them this way to cater to programmers coming from a
   Haskell background, and am hesitant to change them.

   Functoid types.  The obvious alternative to naming the type of a
   functoid with a leading capital letter (e.g. compose has type
   Compose) is to add a suffix (e.g. make it so compose has type
   compose_type).  Functoid type names are used a lot, though, and I
   am not fond of the idea of making the type names longer than the
   names of the instances.

I dunno if either of the examples above constitutes reason enough to
bend the rules with regards to naming conventions, but I want to ask.
   
-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


[boost] Interest in FC++?

2003-06-25 Thread Brian McNamara
I would like to see if there is interest in incorporating the FC++
library into Boost.  

FC++ is a library for functional programming.  In FC++ we program with
functoids (classes which define operator() and obey certain other
conventions).  The library features include:
 - higher order, polymorphic (template) functions (direct functoids)
 - lazy lists
 - library of useful functions, combinators, and monads (mostly
   mimicking the Standard Library of the language Haskell)
 - currying
 - infix function syntax
 - dynamically bound functions (indirect functoids)
 - effect combinators
 - interfaces to STL via iterators
 - ways to transform normal C++ functions/methods into functoids
 - reference-counted pointers
 - a lambda sublanguage, with syntax for lambda, let, letrec, 
   do-notation, and monad comprehensions
Much of the documentation for FC++ can be found at
   http://www.cc.gatech.edu/~yannis/fc++/
and the rest appears linked from
   http://www.cc.gatech.edu/~yannis/fc++/New1.5/
(which has a pre-release of the upcoming version (v1.5), currently out 
for beta-testing).  The upcoming release comprises about 9000 lines of
code and compiles on a number of different compilers (g++, Comeau,
Intel, MSVC++).

I have received mail a couple times in the past few years expressing 
interest in adding FC++ to Boost.  However until now, I have been
unwilling (1) to do the work to Boostify the library, and (2) to lose 
any creative control to tinker with things on my own whims.  I think
now the library has finally settled down, and all the major features I
have wanted to add are included in the upcoming release (v1.5) of
FC++.  And I have some free time this summer to do the work.  Which is
why I'm now finally talking to you-all.

So I am sending this mail to see:
 (1) If there is still interest in adding FC++ to Boost, and
 (2) If there is interest, what-all needs to be changed with the FC++ 
 library to make it meet the standards of Boost.

With regards to (1), I hope yes, but the Boost Lambda Library has a bit
of conceptual overlap with FC++, so I can imagine this issue being
potentially contentious.  (FC++ and Lambda ostensibly provide much of the
same kinds of functionality, but while there is overlap, each library
does a lot of its own thing too.  I (and Jaakko too, probably) can say
more about this if necessary.)

With regards to (2), I have been reading all the stuff on the Boost web 
site regarding submissions, and so I am aware of a number of issues, 
including:
 - Reuse: FC++ reinvents a number of Boost's libraries in its
  implementation, such as smart pointers and metaprogramming
  tricks.  A Boost version of FC++ should reuse Boost libraries for
  this.
 - Documentation: as of yet, there is no good singular users guide for
  FC++ aimed at the audience of C++ programmers; I'd need to write 
  one.
 - Naming conventions: FC++ uses a naming convention other than Boost's
  (including systematically using capital letters in identifiers).
But at this point I'm probably already getting ahead of myself.  So I'll
stop talking and ask people to comment with regards to interest in
FC++.

Thanks,
   Brian

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost