On Fri, 26 Feb 2010, Mindaugas Kavaliauskas wrote:

Hi,

> >In class implementation we are using:
> >   _HB_CLASS <className> [,<classFuncName>]     // new class
> >   _HB_MEMBER <messageName> [ AS <type> ]
> >   _HB_MEMBER { [ AS <type> ] <varName,...> }
> >Of course this is also [x]Harbour only extension and it's hidden for
> >users by PP rules in hbclass.ch so I think that only few people knows
> >about such syntax extension.
> I've seen it a lot of times in .ch and .ppo. I've even tried to look
> into .y for exact meaning of this, but I failed to find a good
> answer in compiler source.

Probably because it seems to be unfinished extension.
Anyhow I plan to fully remove it and create new code from scratch.

> >But for variable declaration in [x]Harbour "AS <type>" can be used after
> >each variable, i.e.:
> >   LOCAL cVar AS CHARACTER, nVar AS NUMERIC, lVar AS LOGICAL
> >This is incompatible with other xbase dialects which allow to use
> >"AS <type>" only at the end and it describes type for all vairables
> >in given declaration, i.e.:
> >   LOCAL nVar1, nVar2, nVar3 AS NUMERIC
> >In FlagShip and VO declares 3 numeric variables but in [x]Harbour
> >only nVar3 is declared as numeric variable but nVar1 and nVar2 do
> >not have strong type, they are AS USUAL.
> >I do not like this difference and it may cause serious problems
> >with code portability.
> >Clipper uses very similar syntax when fields are declared:
> >   FIELD <fieldName, ...> IN <alias>
> >and "IN <alias>" is used for all fields not only for the last one
> >so this [x]Harbour extension looks ugly even if compared with only
> >other Clipper commands.
> I think we must be compatible with majority here. Unless we see a
> drawbacks in majority syntax.

Fine, seems that this part is clear.

> I remember I had some problems in the past introducing new
> operators. AFAIR, it was because PP do not know anything about
> operator precendence. Do we have a same situation here?

Yes. PP does not know anything about operator precedence.
It can only recognize some non literal tokens as part of
expression or concatenating expressions and group expressions
using parenthesis.
In this particular case the precedence is less important.
The problem is caused by the fact the any identifiers cannot
be used to concatenate expressions and in code like:
   ? var as numeric
PP recognize 'var as numeric' as three different expressions
not a single expression so
   #command ? <params,...> => QOut( <params> )
does not match above line.
It can be translated by:
   #command ? <p1> <p2> <p3> => QOut( <p1> <p2> <p3> )
If we do not use construction which is PP friendly then people
will report problems that casting does not work in different
commands.

> Pseudo functions looks like a good solution if we do not want to
> invent a new syntax like var.type . New syntax sometimes has a
> hidden drawbacks if you do not have the whole picture of
> lexer-PP-Compiler in your head. Of cause, I'm sure Przemek has it in
> his head :) But var.type looks a little alien for me.

I'm ready for any other propositions.
In fact we will need it only for maximum warning level when
AS USUAL values are passed as strong parameters or assigned
to strongly typed values to pacify the compile time warning.

> One more thing is very interesting to me: how can we optimize code
> using strong typing? It would be nice, if we can reach a speed of C
> language here :) But we have some problems, f.e., our numeric type
> actually are 3 different types in VM: int, HB_LONG (or some new type
> name to be exact), and double. This disables:
>   LOCAL n1, n2, n3 AS NUMERIC
>   n1 := n2 + n3
> to be optimized to C level + operation, because additional type and
> parameter range checking is required. I've done some comparison of
> different languages (Harbour, Ruby, PHP, Java, etc) in the past.
> Languages that have separate double and integer types has much
> better performance for a simple arithmetic operations.
>   LOCAL n1, n2, n3 AS INTEGER
> could be useful.

We definitely need INTEGER type (it's even already used in Harbour class
code).
We can try to use it to optimize generated code but we can also intorduce
new declarations like in FlagShip:
   STATIC_<TYPE> ...
   LOCAL_<TYPE> ...
i.e.:
   LOCAL_INT i1, i2, i3
   LOCAL_DOUBLE n2, n2, n3
We do not need such declaration for PRIVATE, PUBLIC and FIELD because
they cannot be safely optimized.
Separate declaration makes internal compiler code much cleaner and allow
users to control which parts should be optimized. It means that we can
intorduce some more strict conditions for such strongly typed variables,
i.e. we can forbid passing them by reference or detach in codeblocks.
Personally I would like to make it in such way.

> I also want to answer here to a topic from another thread. This is
> related to Harbour syntax.
> >Example:
> >>with object MyObject
> >>    &( "{|| x := :MyMethod() }" )
> >>end
> >>It gives a syntax error &
> >In next commit I'll add only protection for such GPF (it will work
> >like in xHarbour) and we can try to talk about the future of WITH OBJECT.
> >Here is the code which illustrates the problem:
> >   proc main()
> >      local cb
> >      with object .F.
> >         with object 0
> >            cb := {|| :className }
> >            ? eval( cb )            // NUMERIC
> >         end
> >         ? eval( cb )               // LOGICAL
> >      end
> >      ? eval( cb )                  // GPF or NIL after incomming commit.
> >   return
> >As you can see codeblock is created inside 'with object 0' statement but
> >can be used outside this statement when the given object does not longer
> >exist so it does not confirm WITH OBJECT specification and has to be fixed.
> >We have two choices:
> >   1) detach WITH OBJECT variable lust like local variables
> >      and add code which will resolve references in each :<msg> code.
> >      It will cause some small speed overhead but it will work
> >   2) forbid using :<msg> in nested code blocks at compile time.
> >If we want to add support for macrocompiler then we can chose only
> >method one.
> >But method one except some small speed overhead has yet another drawback.
> >It needs to keep current code which uses additional HVM stack register
> >(lWithObject) to store offset of WITH OBJECT value. Such implementation
> >needs additional code to update lWithObject register at the beginning and
> >end of WITH OBJECT statement (additional speed overhead which can be
> >eliminated and reduces this feature to only single WITH OBJECT variable
> >and this is sth what I would like to eliminate in the future.
> 
> I know my opinion will be not popular, but I think the best choice
> is to remove this xHarbour's extension... Because it falls under
> category:
> 
> >I can understand that we are removing some code/functionality when
> >we have very serious reasons for it, i.e. extension has some bad side
> >effects, it's hard to update/keep alive and consumes too much developer
> >time or blocks some other much more important modifications. In such
> >case we can only say sorry and try to explain the reasons of our
> >decision.

And I agree with you.
When I'll add support for temporary variables then we will return
to this subject and decide what to do with WITH OBJECT statement and
scope of FOR EACH iterator variable.

best regards,
Przemek
_______________________________________________
Harbour mailing list (attachment size limit: 40KB)
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour

Reply via email to