Hi,
Przemysław Czerpak wrote:
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.
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.
The most natural seems to be using pseudo functions like:
asCharacter( <exp> )
asNumeric( <exp> )
asLogical( <exp> )
other method is using some new operator which will work well with PP.
I.e. instead of 'AS' we can use '.AS.' because expressions like
<exp> .AS. <type> are recognized by PP s single expression, i.e.
? x .as. numeric
is well preprocessed by PP to:
QOUT( x .as. numeric )
Please think about it.
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?
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.
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.
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.
Regards,
Mindaugas
_______________________________________________
Harbour mailing list (attachment size limit: 40KB)
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour