Thread overview
Programmable block statements.
Jan 21, 2003
anderson
Jan 21, 2003
Mike Wynn
Jan 21, 2003
Mike Wynn
Jan 21, 2003
anderson
Jan 21, 2003
Mike Wynn
Jan 21, 2003
Scott Pigman
Re: Programmable block statements. - you can already
Jan 21, 2003
Paul Stanton
Jan 21, 2003
Paul Stanton
Jan 21, 2003
Patrick Down
Jan 21, 2003
Mark Evans
January 21, 2003
Yet again, another idea.

I think it would be cool if you could program your own block statements. Often you need to have open/close statements (like with files). If you can force the user to call them in a certain order using programmable block statements, I think it would save a lot of bugs.

Of course the idea I present here is only a prototype.

Class ABC
{
    void open(char * FileName, block Enter)
    {
        if (Enter)
        {
            ...
        }
        else
        {
            ...
        }
    }
}

...

ABC x;

x.open("filename")
{

} //Closes here

You could also handle return types (if it had one). V would only be returned
after open (enter) had completed.

v = x.open("filename")
{

} //Closes here

And you could also use the function as-per-normal where block = boolean.

x.open("filename", true)
x.open("filename", false)

PS - I would suppose there were lots of ways of syntax'ing this, I tried to choose an easily phaseable one.


January 21, 2003
use an auto class

File f;
if ( f = open() )
{
    auto FileCloser = new FileCloser( f );

   // closes here;
}

// I've not checked but you should be able to do;
auto class File {  }

whatever func( char[] name )
{
    char [] fullname = getFulName( name, cwd() );
    {  // braces SHOULD create a new scope (as in C)
        auto MyFile = new MyFile( fullname );
        ... stuff ...
        // will close here
    }
}


"anderson" <anderson@badmama.com.au> wrote in message news:b0ica3$21sj$1@digitaldaemon.com...
> Yet again, another idea.
>
> I think it would be cool if you could program your own block statements. Often you need to have open/close statements (like with files). If you can force the user to call them in a certain order using programmable block statements, I think it would save a lot of bugs.
>
> Of course the idea I present here is only a prototype.
>
> Class ABC
> {
>     void open(char * FileName, block Enter)
>     {
>         if (Enter)
>         {
>             ...
>         }
>         else
>         {
>             ...
>         }
>     }
> }
>
> ...
>
> ABC x;
>
> x.open("filename")
> {
>
> } //Closes here
>
> You could also handle return types (if it had one). V would only be
returned
> after open (enter) had completed.
>
> v = x.open("filename")
> {
>
> } //Closes here
>
> And you could also use the function as-per-normal where block = boolean.
>
> x.open("filename", true)
> x.open("filename", false)
>
> PS - I would suppose there were lots of ways of syntax'ing this, I tried
to
> choose an easily phaseable one.
>
>


January 21, 2003
On Tue, 21 Jan 2003 10:50:41 +0800, anderson wrote:

> Yet again, another idea.
> 
> I think it would be cool if you could program your own block statements. Often you need to have open/close statements (like with files). If you can force the user to call them in a certain order using programmable block statements, I think it would save a lot of bugs.
> 

i second this.
January 21, 2003
a nice idea: improves readability by ensuring variables fall out of scope when no longer needed therefore allowing the reader to disregard such properties (which can also be achieved by writing a method somewhere else, but if your sure you arnt gonna use it again, whats the point?).

basically, by doing this, you are saying "everything between "{" and "}" is only required for [insert purpose here].

But this is not such a new idea, and can be easily achieved syntaxically in current languages. You can use "{" and "}" anywhere you like, they are "scope" parenthesis, therefore, anything defined inside, will fall out of scope when exited.

You can already program yr own block statements


January 21, 2003
ok, i missed the point


January 21, 2003
an example ....

pity you can't `with` an auto

then main could be

int main( char[][] args )
{
 MyFile res;
 printf("Starting ...\n");
 with( new Closer( new closer.MyBlock( &closeIt, 3, res ) ) ) {
  printf("[doing stuff]\n");
 }
 printf("end.\n");

 return 0;
}

almost exactly what you are after.

----------------------------
import c.stdio;

interface Closes
{
 bit close();
}

// work around because you can't have a destructor in a templated class
auto class Closer
{
 Closes toClose;
 this( Closes toClose0 ) { toClose = toClose0; }
 ~this() { toClose.close(); }
}

template delegatehelper( P, RV, T : RV (*)( P ) )
{
  class FcHelper
  {
   T toCall;
   this( T funcPtr ) { toCall = funcPtr; }
   RV evoke( P param ) { return toCall( param ); }
  }
}

template autocloser( T, P )
{
// auto class MyBlock
 class MyBlock : Closes
 {
  alias bit delegate ( T ) closeDelegate;
  alias bit (*closeFuncPtr)( T );

  closeDelegate onClose;
  T item;
/*  this( closeDelegate close0, P param, out T made )
  {
   init( close0, param, made );
  }*/

  this( closeFuncPtr close0, P param, out T made )
  {
   instance delegatehelper( T, bit, closeFuncPtr ) dh;
   dh.FcHelper conv = new dh.FcHelper( close0 );
   init( &conv.evoke, param, made );
  }

  void init( closeDelegate close0, P param, out T made )
  {
   made = item = new T( param );
   onClose = close0;
  }

/*  ~this()
  {
//   onClose( item );
  }*/

  bit close()
  {
   return onClose( item );
  }
 }
}

class MyFile { int i; this( int ii ) { i = ii; printf( "OPEN(%d)\n",
i ); } }


bit closeIt( MyFile f )
{
 printf( "CLOSE\n" );
 return true;
}

instance autocloser( MyFile, int ) closer;

int main( char[][] args )
{
 MyFile res;
 printf("Starting ...\n");
 {
  auto Closer autoClose = new Closer( new closer.MyBlock( &closeIt, 3,
res ) );
  printf("[doing stuff]\n");
 }
 printf("end.\n");

 return 0;
}



January 21, 2003
Close, but not quite. With that technique you need to create an object each time you want this ability. But I get your point about it almost being in the language.

Another point with that example is that it's weakly defined (in reguards to using bracks or not) , because the users won't be force into using the brake scope, which is an the idea I put forth.

"Mike Wynn" <mike.wynn@l8night.co.uk> wrote in message news:b0ih2k$24c9$1@digitaldaemon.com...
> an example ....
>
> pity you can't `with` an auto
>
> then main could be
>
> int main( char[][] args )
> {
>  MyFile res;
>  printf("Starting ...\n");
>  with( new Closer( new closer.MyBlock( &closeIt, 3, res ) ) ) {
>   printf("[doing stuff]\n");
>  }
>  printf("end.\n");
>
>  return 0;
> }
>
> almost exactly what you are after.
>
> ----------------------------
> import c.stdio;
>
> interface Closes
> {
>  bit close();
> }
>
> // work around because you can't have a destructor in a templated class
> auto class Closer
> {
>  Closes toClose;
>  this( Closes toClose0 ) { toClose = toClose0; }
>  ~this() { toClose.close(); }
> }
>
> template delegatehelper( P, RV, T : RV (*)( P ) )
> {
>   class FcHelper
>   {
>    T toCall;
>    this( T funcPtr ) { toCall = funcPtr; }
>    RV evoke( P param ) { return toCall( param ); }
>   }
> }
>
> template autocloser( T, P )
> {
> // auto class MyBlock
>  class MyBlock : Closes
>  {
>   alias bit delegate ( T ) closeDelegate;
>   alias bit (*closeFuncPtr)( T );
>
>   closeDelegate onClose;
>   T item;
> /*  this( closeDelegate close0, P param, out T made )
>   {
>    init( close0, param, made );
>   }*/
>
>   this( closeFuncPtr close0, P param, out T made )
>   {
>    instance delegatehelper( T, bit, closeFuncPtr ) dh;
>    dh.FcHelper conv = new dh.FcHelper( close0 );
>    init( &conv.evoke, param, made );
>   }
>
>   void init( closeDelegate close0, P param, out T made )
>   {
>    made = item = new T( param );
>    onClose = close0;
>   }
>
> /*  ~this()
>   {
> //   onClose( item );
>   }*/
>
>   bit close()
>   {
>    return onClose( item );
>   }
>  }
> }
>
> class MyFile { int i; this( int ii ) { i = ii; printf( "OPEN(%d)\n",
> i ); } }
>
>
> bit closeIt( MyFile f )
> {
>  printf( "CLOSE\n" );
>  return true;
> }
>
> instance autocloser( MyFile, int ) closer;
>
> int main( char[][] args )
> {
>  MyFile res;
>  printf("Starting ...\n");
>  {
>   auto Closer autoClose = new Closer( new closer.MyBlock( &closeIt, 3,
> res ) );
>   printf("[doing stuff]\n");
>  }
>  printf("end.\n");
>
>  return 0;
> }
>
>
>


January 21, 2003
if you could use an auto class with `with`
it's almost there, in your example you use one method with a bool param to
say open or close
the with way
with( new MyAutoObject( params ) ) {  // constructor called
 ... do stuff ...
} /// ~this (destructor called)

does everything you want, no syntax changes, no special cases.

as for creating an object every time, well D is a OO lang.

I don't know if they are, but auto objects could be stack allocated so there
is no overhead createing the space
(just sub sp, (sizeof(locals)+sizeof(autos)) in the function prolog.)
if your class only have methods and no members or few members its no great
overhead.

its basically the same technique C++ programmers have used for years, with
Lock and smart pointer classes
only C++ template syntax is a bit less verbose;


"anderson" <anderson@badmama.com.au> wrote in message news:b0ikm4$262l$1@digitaldaemon.com...
> Close, but not quite. With that technique you need to create an object
each
> time you want this ability. But I get your point about it almost being in the language.
>
> Another point with that example is that it's weakly defined (in reguards
to
> using bracks or not) , because the users won't be force into using the
brake
> scope, which is an the idea I put forth.
>



January 21, 2003
Ruby has a syntax that is similar to this. In Ruby
you could use the following program to write each line
in a file.

File.open("name","r") do |aFile|
  aFile.each_line() do |aLine|
    puts aLine
  end
end

open might be defined like this

def File.open(name,mode)
  aFile = File.new(name,mode)
  yield aFile
  aFile.close()
end

In principal I like the idea.  From an
implementaion standpoint the block that
follows the function is really just an
anonymous function;

Anonymous functions have already been
suggested.

void Func(int b, int (*fp)(int));

Func(12,anon(a){ return a*a;});

Perhaps if the last parameter in a
functions parmeter list was a function
pointer the anonymous function could be
specified after the ')'.

Func(12) anon(a)
{
    	return a*a;
}

This would make the anonymous function look a little cleaner if it was more than a couple of lines long.

"anderson" <anderson@badmama.com.au> wrote in news:b0ica3$21sj$1@digitaldaemon.com:

> Yet again, another idea.
> 
> I think it would be cool if you could program your own block statements. Often you need to have open/close statements (like with files). If you can force the user to call them in a certain order using programmable block statements, I think it would save a lot of bugs.
> 
> Of course the idea I present here is only a prototype.
> 
> Class ABC
> {
>     void open(char * FileName, block Enter)
>     {
>         if (Enter)
>         {
>             ...
>         }
>         else
>         {
>             ...
>         }
>     }
> }
> 
> ...
> 
> ABC x;
> 
> x.open("filename")
> {
> 
> } //Closes here
> 
> You could also handle return types (if it had one). V would only be
> returned after open (enter) had completed.
> 
> v = x.open("filename")
> {
> 
> } //Closes here
> 
> And you could also use the function as-per-normal where block = boolean.
> 
> x.open("filename", true)
> x.open("filename", false)
> 
> PS - I would suppose there were lots of ways of syntax'ing this, I tried to choose an easily phaseable one.
> 
> 

January 21, 2003
The Oz book covers such material.  What you are talking about relates to the dataflow paradigm and also to threads.  Oz has a whole raft of capability relating to threads, distributed stores that appear as one, etc.

Mark